/*乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗//
    bolalg.c
//乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗*/

#include <windows.h>

#include <malloc.h>
#define  _USE_MATH_DEFINES
#include <math.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "bolalg.h"

#define  MODNAM  "BOLALG"
#define  MODVER  OCTVAL(2,6,0,0)

//乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗//

void WINAPI memswap(pANY p1, pANY p2, I4B n)
{ // 抣偺岎姺
  I4B i, m;
  U1B bf[LBUF];

  if (n >= LBUF) {
    for (i = 0, m = n / LBUF; i < m; i++) {
      memcpy(bf, p1, LBUF); memcpy(p1, p2, LBUF); memcpy(p2, bf, LBUF);
     ((pBIN)p1) += LBUF; ((pBIN)p2) += LBUF;
    }
    n = n % LBUF;
  }
  for (i = 0, m = n / 4; i < m; i++) {
    *(pI4B)bf = *(rI4B)p1; *((pI4B)p1)++ = *(rI4B)p2; *((pI4B)p2)++ = *(rI4B)bf;
  }
  for (i = 0, m = n % 4; i < m; i++) {
    *(pU1B)bf = *(rU1B)p1; *((pU1B)p1)++ = *(rU1B)p2; *((pU1B)p2)++ = *(rU1B)bf;
  }
}

void WINAPI memrotl(pANY pv, I4B ln, I4B n)
{ // 僶僀僩楍偺嵍夞揮
  I4B i, m;
  pANY p1, p2;
  U1B bf[LBUF];

  if (n < 0) { memrotr(pv, ln, -n); return;} else if (n >= ln) return;
  if (n >= LBUF) {
    p1 = (pBIN)pv + LBUF; p2 = (pBIN)pv + ln - LBUF;
    for (i = 0, m = n / LBUF; i < m; i++) {
      memcpy(bf, pv, LBUF); memmove(pv, p1, ln - LBUF); memcpy(p2, bf, LBUF);
    }
    n = n % LBUF;
  }
  p1 = (pBIN)pv + 4; p2 = (pBIN)pv + ln - 4;
  for (i = 0, m = n / 4; i < m; i++) {
    *(pI4B)bf = *(rI4B)pv; memmove(pv, p1, ln - 4); *(pI4B)p2 = *(rI4B)bf;
  }
  p1 = (pBIN)pv + 1; p2 = (pBIN)pv + ln - 1;
  for (i = 0, m = n % 4; i < m; i++) {
    *(pU1B)bf = *(rU1B)pv; memmove(pv, p1, ln - 1); *(pU1B)p2 = *(rU1B)bf;
  }
}

void WINAPI memrotr(pANY pv, I4B ln, I4B n)
{ // 僶僀僩楍偺塃夞揮
  I4B i, m;
  pANY p1, p2;
  U1B bf[LBUF];

  if (n < 0) { memrotl(pv, ln, -n); return;} else if (n >= ln) return;
  if (n >= LBUF) {
    p1 = (pBIN)pv + LBUF; p2 = (pBIN)pv + ln - LBUF;
    for (i = 0, m = n / LBUF; i < m; i++) {
      memcpy(bf, p2, LBUF); memmove(p1, pv, ln - LBUF); memcpy(pv, bf, LBUF);
    }
    n = n % LBUF;
  }
  p1 = (pBIN)pv + 4; p2 = (pBIN)pv + ln - 4;
  for (i = 0, m = n / 4; i < m; i++) {
    *(pI4B)bf = *(rI4B)p2; memmove(p1, pv, ln - 4); *(pI4B)pv = *(rI4B)bf;
  }
  p1 = (pBIN)pv + 1; p2 = (pBIN)pv + ln - 1;
  for (i = 0, m = n % 4; i < m; i++) {
    *(pU1B)bf = *(rU1B)p2; memmove(p1, pv, ln - 1); *(pU1B)pv = *(rU1B)bf;
  }
}

I4B  WINAPI sign(F8B d)
{ // double偺惓晧偺敾掕
  return (d > 0.0)? 1: (d < 0.0)? -1: 0;
}

I4B  WINAPI iround(F8B d)
{ // double傪巐幪屲擖偟偰int偵曄姺
  return (d >= 0.0)? (I4B)(d + 0.5): (I4B)(d - 0.5);
}

U4B  WINAPI hash(rSTR st, U4B hs)
{ // 暥帤楍偺僴僢僔儏抣
  I4B va;

  for (va = 0; *st; st++) {
    va = ((va << 8) + *st) % hs;
  }
  return va;
}

U4B  WINAPI nbound(U4B i, U4B n)
{ // 巜掕扨埵偱愗傝忋偘
  return ((i + n - 1) / n) * n;
}

U4B  LOCALF roundup(U4B cap, U4B sz)
{ // 嵟戝梫慺悢偺愗傝忋偘
  U4B n;

  for (n = 32; n < 65536; n *= 2) {
    if (n > cap) { return n;} else if (n * sz >= 65536) break;
  }
  return nbound(cap, n);
}

HMEM WINAPI CreatePtrList(I4B cap)
{ // 僸乕僾儊儌儕娗棟忣曬嶌惉
  HBLK mb;
  P4B pv;

  mb = malloc(sizeof(BLKE)); if (!mb) { return ierr(E_MEM);}
  pv = malloc(cap * sizeof(P4B)); if (!pv) { free(mb); return ierr(E_MEM);}
  return (HMEM)BuildArray(mb, pv, 0, cap, sizeof(P4B));
}

void WINAPI DeletePtrList(HMEM hm)
{ // 僸乕僾儊儌儕娗棟忣曬嶍彍
  if (!hm) return;
  free(((HBLK)hm)->ptr);
  free(hm);
}

BOOL WINAPI AddPtr(HMEM hm, pANY pv)
{ // 億僀儞僞偺捛壛
  HBLK mb = (HBLK)hm;
  I4B cap;
  P4B pr;

  if (mb->len >= mb->cap) {
    cap = roundup(mb->cap + 1, sizeof(P4B));
    pr = realloc(mb->ptr, cap * sizeof(P4B)); if (!pr) { return (BOOL)ierr(E_MEM);}
    mb->ptr = pr;
    mb->cap = cap;
  }
  ((pP4B)mb->ptr)[mb->len++] = pv;
  return TRUE;
}

BOOL WINAPI RemovePtr(HMEM hm, pANY pv)
{ // 億僀儞僞偺嶍彍
  return RemoveItem((HBLK)hm, &pv);
}

  // 婛掕偺僸乕僾儊儌儕娗棟忣曬
static HMEM hMEM;

pANY WINAPI halloc(U4B sz, BOOL clr)
{ // 僸乕僾儊儌儕偺妱傝摉偰
  P4B pv;

  pv = clr? calloc(sz, 1): malloc(sz);
  if (pv) { AddPtr(hMEM, pv);}
  return pv;
}

pANY WINAPI hrealloc(pANY pv, U4B sz)
{ // 僸乕僾儊儌儕偺嵞妱傝摉偰
  P4B pr;

  pr = realloc(pv, sz);
  if (pr) { RemovePtr(hMEM, pv); AddPtr(hMEM, pr);}
  return pr;
}

BOOL LOCALF isheap(pANY pv)
{ // 僸乕僾偵妱傝摉偰傜傟偨億僀儞僞
  return RSearchItemValue((HBLK)hMEM, &pv) >= 0;
}

BOOL WINAPI hfree(pANY pv)
{ // 僸乕僾儊儌儕偺夝曻
  if (!isheap(pv)) return FALSE;
  free(pv);
  RemovePtr(hMEM, pv);
  return TRUE;
}

pANY WINAPI walloc(HMEM hm, U4B sz, BOOL clr)
{ // 僸乕僾儊儌儕偺妱傝摉偰
  P4B pv;

  pv = halloc(sz, clr);
  if (pv) { AddPtr(hm, pv);}
  return pv;
}

pANY WINAPI wrealloc(HMEM hm, pANY pv, U4B sz)
{ // 僸乕僾儊儌儕偺嵞妱傝摉偰
  P4B pr;

  pr = hrealloc(pv, sz);
  if (pr) { RemovePtr(hm, pv); AddPtr(hm, pr);}
  return pr;
}

BOOL LOCALF iswheap(HMEM hm, pANY pv)
{ // 僸乕僾偵妱傝摉偰傜傟偨億僀儞僞
  return RSearchItemValue((HBLK)hm, &pv) >= 0;
}

BOOL WINAPI wfree(HMEM hm, pANY pv)
{ // 僸乕僾儊儌儕偺夝曻
  if (!iswheap(hm, pv)) return FALSE;
  hfree(pv);
  RemovePtr(hm, pv);
  return TRUE;
}

void WINAPI ClearAll(HMEM hm)
{ // 僸乕僾儊儌儕偺慡夝曻
  I4B i;
  HBLK mb = (HBLK)hm;

  for (i = mb->len - 1; i >= 0; i--) {
    hfree(((pP4B)mb->ptr)[i]);
  }
  mb->len = 0;
}

  // 弞娐僶僢僼傽(暥帤楍憖嶌梡)
static U1B  TBUF[8192], *pTB = TBUF;

pANY WINAPI talloc(U4B sz)
{ // 堦帪揑側儊儌儕偺妱傝摉偰
  P4B pt;

  if (sz > LBUF) { ierr(E_CAP);}
  if ((pTB - TBUF) + sz > _countof(TBUF)) { pTB = TBUF;}
  pt = pTB; pTB += sz;
  return pt;
}

  // 弞娐僶僢僼傽(斈梡)
static U1B  UBUF[262144], *pUB = UBUF;

pANY WINAPI ualloc(U4B sz)
{ // 堦帪揑側儊儌儕偺妱傝摉偰
  P4B pt;

  if (sz > _countof(UBUF) / 16) { ierr(E_CAP);}
  sz = nbound(sz, 8);
  if ((pUB - UBUF) + sz > _countof(UBUF)) { pUB = UBUF;}
  pt = pUB; pUB += sz;
  return pt;
}

pANY WINAPI valloc(U4B sz)
{ // 堦帪揑側儊儌儕偺妱傝摉偰(僛儘僋儕傾)
  return memset(ualloc(sz), 0, (sz < _countof(UBUF))? sz: _countof(UBUF));
}

//乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗//

I4B LOCALF lsrch_U4B(rU4B pb, I4B ni, U4B va)
{ // 惍悢抣偺惓弴僒乕僠
  rU4B pc, pe;

  for (pc = pb, pe = pc + ni; pc < pe; pc++) {
    if (*pc == va) { return pc - pb;}
  }
  return -1;
}

I4B LOCALF rsrch_U4B(rU4B pb, I4B ni, U4B va)
{ // 惍悢抣偺媡弴僒乕僠
  rU4B pc;

  for (pc = pb + ni - 1; pc >= pb; pc--) {
    if (*pc == va) { return pc - pb;}
  }
  return -1;
}

I4B LOCALF lsrch_ANY(rANY pb, I4B ni, I4B rsz, rANY pv)
{ // 梫慺偺惓弴僒乕僠
  rBIN pc, pe;

  if (rsz == 4) { return lsrch_U4B(pb, ni, *(rU4B)pv);}
  for (pc = pb, pe = pc + ni * rsz; pc < pe; pc += rsz) {
    if (!memcmp(pc, pv, rsz)) { return (pc - (rBIN)pb) / rsz;}
  }
  return -1;
}

I4B LOCALF rsrch_ANY(rANY pb, I4B ni, I4B rsz, rANY pv)
{ // 梫慺偺媡弴僒乕僠
  rBIN pc;

  if (rsz == 4) { return rsrch_U4B(pb, ni, *(rU4B)pv);}
  for (pc = (rBIN)pb + (ni - 1) * rsz; pc >= (rBIN)pb; pc -= rsz) {
    if (!memcmp(pc, pv, rsz)) { return (pc - (rBIN)pb) / rsz;}
  }
  return -1;
}

I4B  WINAPI idxval(rIDXS ls, I4B id)
{ // 僀儞僨僢僋僗偺帵偡惍悢抣
  return (id >= 0 && id < ls->ni)? ls->pi[id]: 0;
}

I4B  WINAPI srchidx(rIDXS ls, I4B va)
{ // 惍悢抣傪帵偡僀儞僨僢僋僗
  return lsrch_U4B(ls->pi, ls->ni, va);
}

I4B  WINAPI mapval(rMAPS ls, I4B ky)
{ // 僐乕僪斣崋傪惍悢抣偵曄姺
  rMAPI pc, pe;

  for (pc = ls->pv, pe = pc + ls->ni; pc < pe; pc++) {
    if (pc->ky == ky) { return pc->va;}
  }
  return 0;
}

I4B  WINAPI srchmap(rMAPS ls, I4B va)
{ // 惍悢抣傪僐乕僪斣崋偵曄姺
  rMAPI pc, pe;

  for (pc = ls->pv, pe = pc + ls->ni; pc < pe; pc++) {
    if (pc->va == va) { return pc->ky;}
  }
  return -1;
}

rSTR WINAPI enmstr(rENMS ls, I4B va)
{ // 僀儞僨僢僋僗傪暥帤楍偵曄姺
  return (va >= 0 && va < ls->ni)? ls->ps[va]: "";
}

I4B  WINAPI srchenm0(rENMS ls, rSTR st)
{ // 暥帤楍傪僀儞僨僢僋僗偵曄姺
  I4B i;

  for (i = 0; i < ls->ni; i++) {
    if (!strcmp(ls->ps[i], st)) { return i;}
  }
  return -1;
}

rSTR WINAPI codstr(rCODS ls, I4B va)
{ // 僐乕僪斣崋傪暥帤楍偵曄姺
  rCODI pc, pe;

  for (pc = ls->pv, pe = pc + ls->ni; pc < pe; pc++) {
    if (pc->va == va) { return pc->st;}
  }
  return "";
}

I4B  WINAPI srchcod0(rCODS ls, rSTR st)
{ // 暥帤楍傪僐乕僪斣崋偵曄姺
  rCODI pc, pe;

  for (pc = ls->pv, pe = pc + ls->ni; pc < pe; pc++) {
    if (!strcmp(pc->st, st)) { return pc->va;}
  }
  return -1;
}

HBLK WINAPI BuildArray(HBLK mb, pANY pv, I4B len, I4B cap, I4B rsz)
{ // 儊儌儕僽儘僢僋峔憿懱
  mb->ptr = pv;
  mb->len = len;
  mb->cap = cap;
  mb->rsz = rsz;
  return mb;
}

HBLK WINAPI BuildSlice(HBLK mb, HBLK mx, I4B ir, I4B nr)
{ // 斖埻
  mb->ptr = Item(mx, ir);
  mb->len = nr;
  mb->cap = nr;
  mb->rsz = mx->rsz;
  return mb;
}

HBLK WINAPI CreateArray(I4B cap, I4B rsz)
{ // 攝楍嶌惉
  HBLK mb;
  P4B pv;

  mb = halloc(sizeof(BLKE), FALSE); if (!mb) { return ierr(E_MEM);}
  pv = halloc(cap * rsz, FALSE); if (!pv) { hfree(mb); return ierr(E_MEM);}
  return BuildArray(mb, pv, 0, cap, rsz);
}

HBLK WINAPI CreateMemBlk(I4B cap, I4B rsz)
{ // 惷揑攝楍嶌惉
  HBLK mb;

  mb = halloc(sizeof(BLKE) + cap * rsz, FALSE); if (!mb) { return ierr(E_MEM);}
  return BuildArray(mb, (pBIN)mb + sizeof(BLKE), 0, cap, rsz);
}

void WINAPI DeleteArray(HBLK mb)
{ // 攝楍偺嶍彍
  if (!mb) return;
  hfree(mb->ptr);
  hfree(mb);
}

BOOL WINAPI CopyArray(HBLK mb, HBLK mx)
{ // 攝楍偺僐僺乕
  if (mx->len > mb->cap || mb->rsz != mx->rsz) return FALSE;
  memcpy(mb->ptr, mx->ptr, mx->len * mb->rsz);
  mb->len = mx->len;
  return TRUE;
}

BOOL WINAPI AppendArray(HBLK mb, HBLK mx)
{ // 攝楍偺楢寢
  if (mb->len + mx->len > mb->cap || mb->rsz != mx->rsz) return FALSE;
  memcpy((pBIN)mb->ptr + mb->len * mb->rsz, mx->ptr, mx->len * mb->rsz);
  mb->len += mx->len;
  return TRUE;
}

I4B  WINAPI CompareArray(HBLK m1, HBLK m2)
{ // 攝楍偺斾妑
  I4B s1 = m1->len * m1->rsz, s2 = m2->len * m2->rsz;

  if (s1 != s2) { return s1 - s2;}
  return memcmp(m1->ptr, m2->ptr, s1);
}

HBLK WINAPI MakeMemBlk(pANY pv, I4B len, I4B cap, I4B rsz)
{ // 惷揑攝楍椞堟偺愝掕
  return BuildArray(ualloc(sizeof(BLKE)), pv, len, cap, rsz);
}

pANY WINAPI Ptr(HBLK mb)
{ // 攝楍偺愭摢傾僪儗僗
  return mb->ptr;
}

I4B  WINAPI Len(HBLK mb)
{ // 梫慺悢
  return mb->len;
}

I4B  WINAPI ItemSize(HBLK mb)
{ // 梫慺偺僒僀僘
  return mb->rsz;
}

pANY WINAPI Item(HBLK mb, I4B ir)
{ // 梫慺偺傾僪儗僗
  return (pBIN)mb->ptr + ir * mb->rsz;
}

I4B  WINAPI ItemIndex(HBLK mb, rANY pi)
{ // 傾僪儗僗偐傜僀儞僨僢僋僗傪媮傔傞
  return ((rBIN)pi - (rBIN)mb->ptr) / mb->rsz;
}

I4B  WINAPI SetLen(HBLK mb, I4B len)
{ // 梫慺悢偺嵞愝掕
  return mb->len = len;
}

I4B  WINAPI AddLen(HBLK mb, I4B nr)
{ // 梫慺悢偺捛壛
  return mb->len += nr;
}

I4B  WINAPI Capacity(HBLK mb)
{ // 嵟戝梫慺悢
  return mb->cap;
}

BOOL WINAPI ChangeCapacity(HBLK mb, I4B cap)
{ // 嵟戝梫慺悢偺曄峏
  P4B pv;

  if (!isheap(mb->ptr)) { return (BOOL)ierr(E_CAP);}
  pv = hrealloc(mb->ptr, cap * mb->rsz); if (!pv) { return (BOOL)ierr(E_MEM);}
  mb->ptr = pv;
  if (mb->len > cap) { mb->len = mb->cap;}
  mb->cap = cap;
  return TRUE;
}

BOOL LOCALF insert_items(HBLK mb, I4B ir, rANY pb, I4B nr)
{ // 斖埻偺憓擖
  if (mb->len + nr > mb->cap) {
    if (!ChangeCapacity(mb, roundup(mb->cap + nr, mb->rsz))) return FALSE;
  }
  if (ir < mb->len) {
    memmove(Item(mb, ir + nr), Item(mb, ir), (mb->len - ir) * mb->rsz);
  }
  if (!pb) {
    memset(Item(mb, ir), 0, nr * mb->rsz);
  } else {
    memcpy(Item(mb, ir), pb, nr * mb->rsz);
  }
  mb->len += nr;
  return TRUE;
}

BOOL WINAPI InsertItem(HBLK mb, I4B ir, rANY pi)
{ // 梫慺偺憓擖
  if (ir < 0 || ir > mb->len) return FALSE;
  return insert_items(mb, ir, pi, 1);
}

BOOL WINAPI InsertItems(HBLK mb, I4B ir, rANY pb, I4B nr)
{ // 斖埻偺憓擖
  if (ir < 0 || ir > mb->len || nr <= 0) return FALSE;
  return insert_items(mb, ir, pb, nr);
}

BOOL LOCALF delete_items(HBLK mb, I4B ir, I4B nr)
{ // 斖埻偺嶍彍
  if (ir + nr < mb->len) {
    memmove(Item(mb, ir), Item(mb, ir + nr), (mb->len - ir - nr) * mb->rsz);
  }
  mb->len -= nr;
  return TRUE;
}

BOOL WINAPI DeleteItem(HBLK mb, I4B ir)
{ // 梫慺偺嶍彍
  if (ir < 0 || ir >= mb->len) return FALSE;
  return delete_items(mb, ir, 1);
}

BOOL WINAPI DeleteItems(HBLK mb, I4B ir, I4B nr)
{ // 斖埻偺嶍彍
  if (ir + nr > mb->len) { nr = mb->len - ir;}
  if (ir < 0 || ir >= mb->len || nr <= 0) return FALSE;
  return delete_items(mb, ir, nr);
}

BOOL WINAPI AddItem(HBLK mb, rANY pi)
{ // 梫慺偺捛壛
  return insert_items(mb, mb->len, pi, 1);
}

BOOL WINAPI AddItems(HBLK mb, rANY pb, I4B nr)
{ // 梫慺楍偺捛壛
  if (nr <= 0) return FALSE;
  return insert_items(mb, mb->len, pb, nr);
}

pANY WINAPI NewItem(HBLK mb)
{ // 捛壛梫慺
  return insert_items(mb, mb->len, NULL, 1)? Item(mb, mb->len - 1): valloc(mb->rsz);
}

BOOL WINAPI RemoveItem(HBLK mb, rANY pi)
{ // 梫慺偺嶍彍
  I4B ir;

  ir = RSearchItemValue(mb, pi); if (ir < 0) return FALSE;
  return delete_items(mb, ir, 1);
}

BOOL WINAPI PopItem(pANY pi, HBLK mb)
{ // 嵟屻偺梫慺偺庢傝弌偟
  if (mb->len > 0) { mb->len--;} else return FALSE;
  memcpy(pi, Item(mb, mb->len), mb->rsz);
  return TRUE;
}

void LOCALF reverse_items(HBLK mb)
{ // 媡弴暲傋懼偊
  I4B i;

  for (i = 0; i < mb->len / 2; i++) {
    memswap(Item(mb, i), Item(mb, mb->len - 1 - i), mb->rsz);
  }
}

void WINAPI ReverseItems(HBLK mb, I4B ir, I4B nr)
{ // 斖埻偺媡弴暲傋懼偊
  BLKE blk;

  if (ir < 0 || ir >= mb->len || nr <= 0) return;
  reverse_items(BuildSlice(&blk, mb, ir, nr));
}

void LOCALF rotate_items_left(HBLK mb)
{ // 嵍夞揮
  memrotl(mb->ptr, mb->len * mb->rsz, mb->rsz);
}

void LOCALF rotate_items_right(HBLK mb)
{ // 塃夞揮
  memrotr(mb->ptr, mb->len * mb->rsz, mb->rsz);
}

void WINAPI RotateItemsLeft(HBLK mb, I4B ir, I4B nr)
{ // 斖埻偺嵍夞揮
  BLKE blk;

  if (ir < 0 || ir >= mb->len || nr <= 0) return;
  rotate_items_left(BuildSlice(&blk, mb, ir, nr));
}

void WINAPI RotateItemsRight(HBLK mb, I4B ir, I4B nr)
{ // 斖埻偺塃夞揮
  BLKE blk;

  if (ir < 0 || ir >= mb->len || nr <= 0) return;
  rotate_items_right(BuildSlice(&blk, mb, ir, nr));
}

void WINAPI MoveItemToFirst(HBLK mb, I4B ir)
{ // 梫慺傪愭摢偵堏摦
  BLKE blk;

  if (ir < 0 || ir >= mb->len) return;
  rotate_items_right(BuildSlice(&blk, mb, 0, ir + 1));
}

void WINAPI MoveItemToLast(HBLK mb, I4B ir)
{ // 梫慺傪枛旜偵堏摦
  BLKE blk;

  if (ir < 0 || ir >= mb->len) return;
  rotate_items_left(BuildSlice(&blk, mb, ir, mb->len - ir));
}

I4B  WINAPI LSearchItemValue(HBLK mb, rANY pi)
{ // 抣偺惓弴僒乕僠
  return lsrch_ANY(mb->ptr, mb->len, mb->rsz, pi);
}

I4B  WINAPI RSearchItemValue(HBLK mb, rANY pi)
{ // 抣偺媡弴僒乕僠
  return rsrch_ANY(mb->ptr, mb->len, mb->rsz, pi);
}

BOOL WINAPI fselALL(rANY pb, uANY pa)
{ // 偡傋偰慖戰
  return TRUE;
}

BOOL WINAPI fselU1B(rANY pb, uANY pa)
{ // 愭摢偺BYTE偱慖戰
  return *(rU1B)pb == pa;
}

BOOL WINAPI fselU2B(rANY pb, uANY pa)
{ // 愭摢偺WORD偱慖戰
  return *(rU2B)pb == pa;
}

BOOL WINAPI fselU4B(rANY pb, uANY pa)
{ // 愭摢偺int偱慖戰
  return *(rU4B)pb == pa;
}

I4B  WINAPI LSearchItem(HBLK mb, FSEL fsel, uANY pa)
{ // 惓弴僒乕僠
  rBIN pc, pe;

  if (!fsel) return 0;
  for (pc = mb->ptr, pe = pc + mb->len * mb->rsz; pc < pe; pc += mb->rsz) {
    if (fsel(pc, pa)) { return ItemIndex(mb, pc);}
  }
  return -1;
}

I4B  WINAPI RSearchItem(HBLK mb, FSEL fsel, uANY pa)
{ // 媡弴僒乕僠
  rBIN pc;

  if (!fsel) { return mb->len - 1;}
  for (pc = (rBIN)mb->ptr + (mb->len - 1) * mb->rsz; pc >= (rBIN)mb->ptr; pc -= mb->rsz) {
    if (fsel(pc, pa)) { return ItemIndex(mb, pc);}
  }
  return -1;
}

I4B  WINAPI SearchItem(HBLK mb, I4B i0, FSEL fsel, uANY pa)
{ // 僒乕僠
  I4B i;
  BLKE blk;

  if (!fsel) { return i0;}
  i = LSearchItem(BuildSlice(&blk, mb, i0, mb->len - i0), fsel, pa);
  return (i >= 0)? i0 + i: -1;
}

I4B  WINAPI CountItems(HBLK mb, FSEL fsel, uANY pa)
{ // 僇僂儞僩
  I4B i, n;

  if (!fsel) { return mb->len;}
  for (n = i = 0; i < mb->len; i++) {
    if (fsel(Item(mb, i), pa)) { n++;}
  }
  return n;
}

I4B  WINAPI SelectItems(HBLK mb, FSEL fsel, uANY pa)
{ // 峣傝崬傒
  I4B i, n;

  if (!fsel) { return mb->len;}
  for (n = i = 0; i < mb->len; i++) {
    if (fsel(Item(mb, i), pa)) {
      if (i > n) { memcpy(Item(mb, n), Item(mb, i), mb->rsz);}
      n++;
    }
  }
  return mb->len = n;
}

I4B  WINAPI InvSelectItems(HBLK mb, FSEL fsel, uANY pa)
{ // 峣傝崬傒(忦審斀揮)
  I4B i, n;

  if (!fsel) { return mb->len = 0;}
  for (n = i = 0; i < mb->len; i++) {
    if (!fsel(Item(mb, i), pa)) {
      if (i > n) { memcpy(Item(mb, n), Item(mb, i), mb->rsz);}
      n++;
    }
  }
  return mb->len = n;
}

I4B  WINAPI fsrtI1B(rANY p1, rANY p2, uANY pa)
{ // char偲偟偰斾妑
  return *(rI1B)p1 - *(rI1B)p2;
}

I4B  WINAPI fsrtU1B(rANY p1, rANY p2, uANY pa)
{ // BYTE偲偟偰斾妑
  return *(rU1B)p1 - *(rU1B)p2;
}

I4B  WINAPI fsrtI2B(rANY p1, rANY p2, uANY pa)
{ // short偲偟偰斾妑
  return *(rI2B)p1 - *(rI2B)p2;
}

I4B  WINAPI fsrtU2B(rANY p1, rANY p2, uANY pa)
{ // WORD偲偟偰斾妑
  return *(rU2B)p1 - *(rU2B)p2;
}

I4B  WINAPI fsrtI4B(rANY p1, rANY p2, uANY pa)
{ // int偲偟偰斾妑
  return (*(rI4B)p1 > *(rI4B)p2)? 1: (*(rI4B)p1 < *(rI4B)p2)? -1: 0;
}

I4B  WINAPI fsrtU4B(rANY p1, rANY p2, uANY pa)
{ // UINT偲偟偰斾妑
  return (*(rU4B)p1 > *(rU4B)p2)? 1: (*(rU4B)p1 < *(rU4B)p2)? -1: 0;
}

I4B  WINAPI fsrtI8B(rANY p1, rANY p2, uANY pa)
{ // INT64偲偟偰斾妑
  return (*(rI8B)p1 > *(rI8B)p2)? 1: (*(rI8B)p1 < *(rI8B)p2)? -1: 0;
}

I4B  WINAPI fsrtU8B(rANY p1, rANY p2, uANY pa)
{ // UINT64偲偟偰斾妑
  return (*(rU8B)p1 > *(rU8B)p2)? 1: (*(rU8B)p1 < *(rU8B)p2)? -1: 0;
}

I4B  WINAPI fsrtF4B(rANY p1, rANY p2, uANY pa)
{ // float偲偟偰斾妑
  return (*(rF4B)p1 > *(rF4B)p2)? 1: (*(rF4B)p1 < *(rF4B)p2)? -1: 0;
}

I4B  WINAPI fsrtF8B(rANY p1, rANY p2, uANY pa)
{ // double偲偟偰斾妑
  return (*(rF8B)p1 > *(rF8B)p2)? 1: (*(rF8B)p1 < *(rF8B)p2)? -1: 0;
}

void WINAPI SortItems(HBLK mb, FSRT fsrt, uANY pa)
{ // 暲傋懼偊
  I4B g, i, j, s;

  if (!fsrt || mb->len <= 1) return;
  g = mb->len;
  do {
    switch (g = g * 10 / 13) {
    case 0: g = 1; break;
    case 9: case 10: g = 11; break;
    }
    s = 0;
    for (i = 0, j = g; j < mb->len; i++, j++) {
      if (fsrt(Item(mb, i), Item(mb, j), pa) > 0) {
        memswap(Item(mb, i), Item(mb, j), mb->rsz);
        s = 1;
      }
    }
  } while (s != 0 || g > 1);
}

//乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗//

  // 僄儔乕儊僢僙乕僕
static CODI eeALG[256] = {
  { E_MEM, "儊儌儕傾儘働乕僩僄儔乕" },        // 0
  { E_DAT, "晄惓側僨乕僞" },
  { E_PAR, "晄惓側僷儔儊乕僞" },
  { E_FIR, "僼傽僀儖撉崬僄儔乕" },
  { E_FIW, "僼傽僀儖彂弌僄儔乕" },
  { E_DIR, "僼僅儖僟傪嶌惉偱偒側偄" },
  { E_ALO, "僨乕僞奿擺堟偑妋曐偝傟偰偄側偄" },
  { E_CAP, "僨乕僞奿擺堟偺梕検惂尷傪挻偊偨" },
  { E_DLL, "儔僀僽儔儕偺弶婜壔偵幐攕偟偨" },  // 8
};
static CODS emALG = { eeALG, 9 };

BOOL WINAPI register_error_descriptions(rCODS ed)
{ // 僄儔乕儊僢僙乕僕搊榐
  if (emALG.ni + ed->ni > _countof(eeALG)) { return (BOOL)ierr(E_CAP);}
  memcpy(&emALG.pv[emALG.ni], ed->pv, ed->ni * sizeof(CODI));
  emALG.ni += ed->ni;
  return TRUE;
}

rSTR WINAPI error_description(U4B ec)
{ // 僄儔乕儊僢僙乕僕
  return codstr(&emALG, ec);
}

  // 僄儔乕忣曬
static BOOL EMSG = TRUE;
static BOOL ELOG = FALSE;
static U4B  EFST = 0;
static U4B  ELST = 0;

I4B  WINAPI first_error(void)
{ // 嵟弶偺僄儔乕
  return EFST;
}

I4B  WINAPI last_error(void)
{ // 嵟屻偺僄儔乕
  return ELST;
}

void WINAPI reset_error(void)
{ // 僄儔乕忣曬偺僋儕傾
  EMSG = TRUE;
  EFST = ELST = 0;
}

BOOL WINAPI enable_error_reporting(void)
{ // 僄儔乕昞帵嫋壜
  I4B bk = EMSG; EMSG = TRUE; return bk;
}

BOOL WINAPI disable_error_reporting(void)
{ // 僄儔乕昞帵梷巭
  I4B bk = EMSG; EMSG = FALSE; return bk;
}

BOOL WINAPI enable_error_logging(void)
{ // 僄儔乕儘僌傪巆偡愝掕
  I4B bk = ELOG; ELOG = TRUE; return bk;
}

BOOL WINAPI disable_error_logging(void)
{ // 僄儔乕儘僌傪巆偝側偄愝掕
  I4B bk = ELOG; ELOG = FALSE; return bk;
}

BOOL LOCALF ferrNOP(rSTR em, U4B er, rSTR fn, U4B lo)
{ // 僟儈乕
  return TRUE;
}

  // 僄儔乕僴儞僪儔
static FERR errmsg = ferrNOP;
static FERR errlog = ferrNOP;

void WINAPI override_errmsg(FERR fmsg)
{ // 僄儔乕僴儞僪儔偺搊榐
  errmsg = fmsg;
}

void WINAPI override_errlog(FERR flog)
{ // 僄儔乕僴儞僪儔偺搊榐
  errlog = flog;
}

pANY WINAPI throw_error(rSTR em, U4B er, rSTR fn, U4B lo)
{ // 僄儔乕張棟
  if (EMSG) { EMSG = errmsg(em, er, fn, lo);}
  if (ELOG) { errlog(em, er, fn, lo);}
  if (EFST == 0) { EFST = LOU2B(er);}
  ELST = LOU2B(er);
  return NULL;
}

void LOCALF fdebNOP(rSTR st)
{ // 僟儈乕
}

  // 僨僶僢僌梡
static FDEB debmsg = fdebNOP;
static FDEB deblog = fdebNOP;

void WINAPI override_debmsg(FDEB fmsg)
{ // 僨僶僢僌梡儘僈乕偺搊榐
  debmsg = fmsg;
}

void WINAPI override_deblog(FDEB flog)
{ // 僨僶僢僌梡儘僈乕偺搊榐
  deblog = flog;
}

void WINAPI debug_logging(rSTR st)
{ // 僨僶僢僌梡
  if (EMSG) { debmsg(st);}
  if (ELOG) { deblog(st);}
}

//乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗//

#define  VecTmpN(n)  _alloca((n) * sizeof(F8B))
#define  MatTmpN(n)  _alloca((n) * (n) * sizeof(F8B))

pVEC WINAPI VecCpyN(pVEC vr, rVEC vc, I4B n)
{ // 儀僋僩儖偺僐僺乕
  return memcpy(vr, vc, n * sizeof(F8B));
}

F8B  WINAPI VecIprN(rVEC v1, rVEC v2, I4B n)
{ // 儀僋僩儖偺撪愊
  I4B i;
  F8B d = 0.0;

  for (i = 0; i < n; i++) {
    d += v1[i] * v2[i];
  }
  return d;
}

pMAT WINAPI MatCpyN(pMAT mr, rMAT mt, I4B n)
{ // 惓曽峴楍偺僐僺乕
  return memcpy(mr, mt, n * n * sizeof(F8B));
}

pVEC WINAPI MatVecN(pVEC vr, rMAT mt, rVEC vc, I4B n)
{ // 惓曽峴楍偲儀僋僩儖偺愊
  I4B i, j;

  if (vr == vc) { return VecCpyN(vr, MatVecN(VecTmpN(n), mt, vc, n), n);}
  for (i = 0; i < n; i++) {
    vr[i] = 0;
    for (j = 0; j < n; j++) {
      vr[i] += mt[i * n + j] * vc[j];
    }
  }
  return vr;
}

pMAT WINAPI MatMulN(pMAT mr, rMAT m1, rMAT m2, I4B n)
{ // 惓曽峴楍偺愊
  I4B i, j, k;

  if (mr == m1 || mr == m2) { return MatCpyN(mr, MatMulN(MatTmpN(n), m1, m2, n), n);}
  for (i = 0; i < n; i++) {
    for (j = 0; j < n; j++) {
      mr[i * n + j] = 0;
      for (k = 0; k < n; k++) {
        mr[i * n + j] += m1[i * n + k] * m2[k * n + j];
      }
    }
  }
  return mr;
}

F8B  WINAPI MatLudN(pMAT mr, pI4B pi, rMAT mt, I4B n)
{ // LU暘夝
  I4B i, j, k;
  F8B d, t, u, *vw;

  if (mr != mt) { MatCpyN(mr, mt, n);}
  vw = VecTmpN(n);
  for (i = 0; i < n; i++) {
    pi[i] = i;
    u = 0.0;
    for (j = 0; j < n; j++) {
      if ((t = fabs(mr[i * n + j])) > u) { u = t;}
    }
    if (u == 0.0) { return 0.0;}
    vw[i] = u;
  }
  d = 1.0;
  for (i = 0; i < n; i++) {
    u = -1.0;
    for (j = i; j < n; j++) {
      if ((t = fabs(mr[pi[j] * n + i]) / vw[pi[j]]) > u) { u = t; k = j;}
    }
    if (k != i) {
      j = pi[k]; pi[k] = pi[i]; pi[i] = j;
      d = -d;
    }
    u = mr[pi[i] * n + i];
    if (u == 0.0) { return 0.0;}
    d *= u;
    for (j = i+1; j < n; j++) {
      t = (mr[pi[j] * n + i] /= u);
      for (k = i+1; k < n; k++) {
        mr[pi[j] * n + k] -= t * mr[pi[i] * n + k];
      }
    }
  }
  return d;
}

F8B  WINAPI MatDetN(rMAT mt, I4B n)
{ // 峴楍幃偺抣
  return MatLudN(MatTmpN(n), ualloc(n * sizeof(I4B)), mt, n);
}

pMAT WINAPI MatInvN(pMAT mr, rMAT mt, I4B n)
{ // 媡峴楍
  I4B i, j, k, *pi;
  F8B d, t, *mw;

  mw = MatTmpN(n);
  d = MatLudN(mw, pi = ualloc(n * sizeof(I4B)), mt, n);
  if (d == 0.0) return NULL;
  for (k = 0; k < n; k++) {
    for (i = 0; i < n; i++) {
      t = (pi[i] != k)? 0.0: 1.0;
      for (j = 0; j < i; j++) {
        t -= mw[pi[i] * n + j] * mr[j * n + k];
      }
      mr[i * n + k] = t;
    }
    for (i = n-1; i >= 0; i--) {
      t = mr[i * n + k];
      for (j = i+1; j < n; j++) {
        t -= mw[pi[i] * n + j] * mr[j * n + k];
      }
      mr[i * n + k] = t / mw[pi[i] * n + i];
    }
  }
  return mr;
}

BOOL WINAPI EquNu1d(pVEC vr, rMAT mt, rVEC vc, I4B n)
{ // n尦1師曽掱幃傪夝偔
  I4B i, j, *pi;
  F8B d, t, *mw;

  mw = MatTmpN(n);
  d = MatLudN(mw, pi = ualloc(n * sizeof(I4B)), mt, n);
  if (d == 0.0) return FALSE;
  for (i = 0; i < n; i++) {
    t = vc[pi[i]];
    for (j = 0; j < i; j++) {
      t -= mw[pi[i] * n + j] * vr[j];
    }
    vr[i] = t;
  }
  for (i = n-1; i >= 0; i--) {
    t = vr[i];
    for (j = i+1; j < n; j++) {
      t -= mw[pi[i] * n + j] * vr[j];
    }
    vr[i] = t / mw[pi[i] * n + i];
  }
  return TRUE;
}

static I4B  Ncn = 100;
static F8B  Eps = 1E-08;

BOOL WINAPI Equ1uNtn(pF8B px, FVAL fn, FVAL fd, uANY pa)
{ // 僯儏乕僩儞朄偱曽掱幃傪夝偔
  I4B i;
  F8B d, t;

  for (i = 0; i < Ncn; i++) {
    d = fd(*px, pa); if (!d) return FALSE;
    t = fn(*px, pa) / d;
    *px -= t;
    if (fabs(t) <= Eps) return TRUE;
  }
  return FALSE;
}

F8B  LOCALF PolValN(F8B x, rVEC vc, I4B n)
{ // 懡崁幃偺抣
  I4B i;
  F8B d = 1.0;

  for (i = 0; i < n; i++) {
    d = d * x + vc[i];
  }
  return d;
}

F8B  LOCALF PolDerN(F8B x, rVEC vc, I4B n)
{ // 懡崁幃偺摫娭悢偺抣
  I4B i;
  F8B d = n;

  for (i = 0; i < n - 1; i++) {
    d = d * x + (n - i - 1) * vc[i];
  }
  return d;
}

F8B  WINAPI PolMaxN(rVEC vc, I4B n)
{ // 學悢偺愨懳抣偺嵟戝抣
  I4B i;
  F8B d = 0.0, t;

  for (i = 0; i < n; i++) {
    if ((t = fabs(vc[i])) > d) { d = t;}
  }
  return d;
}

void LOCALF PolDiv1(pVEC vr, F8B x, rVEC vc, I4B n)
{ // 慻棫彍朄
  I4B i;
  F8B d = 1.0;

  for (i = 0; i < n; i++) {
    vr[i] = d = d * x + vc[i];
  }
}

  // 懡崁幃偺學悢
typedef struct {
  pVEC  vc;
  I4B   n;
} POLP;

F8B  LOCALF fvalPOL(F8B x, POLP *pa)
{ // 娭悢
  return PolValN(x, pa->vc, pa->n);
}

F8B  LOCALF fvalDER(F8B x, POLP *pa)
{ // 摫娭悢
  return PolDerN(x, pa->vc, pa->n);
}

I4B  WINAPI Equ1uNd(pVEC vr, rVEC vc, I4B n)
{ // 1尦n師曽掱幃傪夝偔
  I4B i;
  POLP w;

  VecCpyN(w.vc = VecTmpN(n), vc, w.n = n);
  for (i = 0; i < n; i++) {
    vr[i] = -(PolMaxN(w.vc, w.n) + 1.0);
    if (!Equ1uNtn(&vr[i], (FVAL)fvalPOL, (FVAL)fvalDER, (uANY)&w)) { return i;}
    PolDiv1(w.vc, vr[i], w.vc, w.n--);
  }
  return i;
}

//乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗//

HIMG WINAPI CreateIMG(I4B w, I4B h, RGBC cb)
{ // 價僢僩儅僢僾夋憸嶌惉
  HIMG im;
  pRGBC bi, pc, pe;

  if (w <= 0 || h <= 0) { return ierr(E_PAR);}
  im = halloc(sizeof(IMGE), FALSE); if (!im) { return ierr(E_MEM);}
  bi = halloc(w * h * sizeof(RGBC), !cb); if (!bi) { return ierr(E_MEM);}
  if (cb) {
    for (pc = bi, pe = pc + w * h; pc < pe; pc++) {
      *pc = cb;
    }
  }
  im->bi = bi; im->w = w; im->h = h;
  return im;
}

HIMG WINAPI DuplicateIMG(HIMG im)
{ // 價僢僩儅僢僾夋憸偺暋惢
  HIMG bx;

  bx = CreateIMG(im->w, im->h, 0); if (!bx) return NULL;
  memcpy(bx->bi, im->bi, im->w * im->h * sizeof(RGBC));
  return bx;
}

void WINAPI DeleteIMG(HIMG im)
{ // 價僢僩儅僢僾夋憸偺嶍彍
  if (!im) return;
  hfree(im->bi);
  hfree(im);
}

HIMG WINAPI MoveIMG(HIMG im, HIMG ix)
{ // 價僢僩儅僢僾夋憸偺堏摦
  hfree(im->bi);
  im->bi = ix->bi; im->w = ix->w; im->h = ix->h;
  hfree(ix);
  return im;
}

#define  bR(cr)  ((pU1B)&(cr))[2]
#define  bG(cr)  ((pU1B)&(cr))[1]
#define  bB(cr)  ((pU1B)&(cr))[0]
#define  bA(cr)  ((pU1B)&(cr))[3]

#define  bC(cr)  ((bG(cr) + bB(cr)) / 2)
#define  bM(cr)  ((bR(cr) + bB(cr)) / 2)
#define  bY(cr)  ((bR(cr) + bG(cr)) / 2)

#define  Wr  0.299
#define  Wg  0.587
#define  Wb  0.114
#define  Mb  ((Wr + Wg) / 0.5)
#define  Mr  ((Wg + Wb) / 0.5)
#define  Ur  (Wr / Mb)
#define  Ug  (Wg / Mb)
#define  Ub  0.5
#define  Vr  0.5
#define  Vg  (Wg / Mr)
#define  Vb  (Wb / Mr)

U1B  WINAPI fvalBRI(RGBC cr)
{ // 柧搙
  return (I4B)(Wr * bR(cr) + Wg * bG(cr) + Wb * bB(cr) + 0.5);
}

U1B  WINAPI fvalCDB(RGBC cr)
{ // 怓嵎(惵)
  return (I4B)(128.0 - Ur * bR(cr) - Ug * bG(cr) + Ub * bB(cr));
}

U1B  WINAPI fvalCDR(RGBC cr)
{ // 怓嵎(愒)
  return (I4B)(128.0 + Vr * bR(cr) - Vg * bG(cr) - Vb * bB(cr));
}

U1B  WINAPI fvalSAT(RGBC cr)
{ // 嵤搙
  F8B db, dr;

  db = fvalCDB(cr) / 255.0 - 0.5;
  dr = fvalCDR(cr) / 255.0 - 0.5;
  return (I4B)(sqrt(db * db + dr * dr) * 255.0 + 0.5);
}

U1B  WINAPI fvalHUE(RGBC cr)
{ // 怓憡
  F8B db, dr;

  db = fvalCDB(cr) / 255.0 - 0.5;
  dr = fvalCDR(cr) / 255.0 - 0.5;
  if (db == 0.0 && dr == 0.0) return 0;
  return (I4B)((atan2(dr, db) + M_PI) * 128.0 / M_PI + 0.5);
}

U1B  WINAPI fvalAVG(RGBC cr)
{ // 暯嬒
  return (bR(cr) + bG(cr) + bB(cr)) / 3;
}

RGBC WINAPI fcvtRBX(RGBC cr, uANY pa)
{ // R佁B岎戙怓(COLORREF佁RGBQUAD曄姺)
  I4B t = bR(cr); bR(cr) = bB(cr); bB(cr) = t; return cr;
}

RGBC WINAPI fcvtGRA(RGBC cr, uANY pa)
{ // 怓惉暘傪僌儔僨乕僔儑儞(怓1仺怓2)偱昞偡
  return foprMIX(((GRAP *)pa)->c2, ((GRAP *)pa)->c1, ((GRAP *)pa)->fcol(cr));
}

RGBC WINAPI fcvtBIN(RGBC cr, uANY pa)
{ // 擇抣壔
  return (((BINP *)pa)->fcol(cr) <= (U1B)((BINP *)pa)->th)? ((BINP *)pa)->c1: ((BINP *)pa)->c2;
}

RGBC WINAPI fcvtGRS(RGBC cr, uANY pa)
{ // 僌儗乕僗働乕儖壔
  static const GRAP gra = { 0, 0xffffff, fvalBRI };

  return fcvtGRA(cr, (uANY)&gra);
}

RGBC WINAPI fcvtLGT(RGBC cr, uANY pa)
{ // 柧埫挷惍(pa:0乣255偱崟仺敀)
  if (pa < 128) {
    return foprMIX(0x000000, cr, 2 * (127 - pa));
  } else if (pa < 256) {
    return foprMIX(0xffffff, cr, 2 * (pa - 127));
  }
  return cr;
}

RGBC WINAPI fcvtGRY(RGBC cr, uANY pa)
{ // 僌儗乕傾僂僩壔(pa:攚宨怓)
  if (cr != pa) {
    bR(cr) = bG(cr) = bB(cr) = (fvalAVG(cr) + fvalAVG(pa) * 2) / 3;
  }
  return cr;
}

RGBC WINAPI fcvtTXT(RGBC cr, uANY pa)
{ // 攚宨怓偵崌偆暥帤怓
  static const BINP bin = { 0xffffff, 0, fvalBRI, 128 };

  return fcvtBIN(cr, (uANY)&bin);
}

void WINAPI ChangeIMGColor(HIMG im, FCVT fcvt, uANY pa)
{ // 怓曄姺
  pRGBC pc, pe;

  for (pc = im->bi, pe = pc + im->w * im->h; pc < pe; pc++) {
    *pc = fcvt(*pc, pa);
  }
}

RGBC WINAPI foprADD(RGBC c1, RGBC c2, uANY pa)
{ // 壛朄崿怓
  I4B va;

  bR(c1) = ((va = bR(c1) + bR(c2) * pa / 255) < 255)? va: 255;
  bG(c1) = ((va = bG(c1) + bG(c2) * pa / 255) < 255)? va: 255;
  bB(c1) = ((va = bB(c1) + bB(c2) * pa / 255) < 255)? va: 255;
}

RGBC WINAPI foprSUB(RGBC c1, RGBC c2, uANY pa)
{ // 尭朄崿怓
  I4B va;

  bR(c1) = ((va = bR(c1) - bC(c2) * pa / 255) < 0)? 0: va;
  bG(c1) = ((va = bG(c1) - bM(c2) * pa / 255) < 0)? 0: va;
  bB(c1) = ((va = bB(c1) - bY(c2) * pa / 255) < 0)? 0: va;
}

RGBC WINAPI foprMIX(RGBC c1, RGBC c2, uANY pa)
{ // 暯嬒崿怓(pa:c1偺斾棪丄0仺255偱0%仺100%)
  I4B w1 = (U1B)pa, w2 = 255 - w1;

  bR(c1) = (bR(c1) * w1 + bR(c2) * w2) / 255;
  bG(c1) = (bG(c1) * w1 + bG(c2) * w2) / 255;
  bB(c1) = (bB(c1) * w1 + bB(c2) * w2) / 255;
  bA(c1) = (bA(c1) * w1 + bA(c2) * w2) / 255;
  return c1;
}

RGBC WINAPI foprALF(RGBC c1, RGBC c2, uANY pa)
{ // 傾儖僼傽抣偵傛傞崿怓(c2.A:c1偺斾棪丄0仺255偱0%仺100%)
  I4B w1 = bA(c2), w2 = 255 - w1;

  bR(c1) = (bR(c1) * w1 + bR(c2) * w2) / 255;
  bG(c1) = (bG(c1) * w1 + bG(c2) * w2) / 255;
  bB(c1) = (bB(c1) * w1 + bB(c2) * w2) / 255;
  return c1;
}

void WINAPI SuperposeIMG(HIMG im, HIMG ix, I4B x, I4B y, FOPR fopr, uANY pa)
{ // 廳偹崌傢偣
  I4B i, j, k, l;

  for (i = 0; i < ix->h; i++) {
    k = y + i; if (k < 0 || k >= im->h) continue;
    for (j = 0; j < ix->w; j++) {
      l = x + j; if (l < 0 || l >= im->w) continue;
      im->bi[k * im->w + l] = fopr(im->bi[k * im->w + l], ix->bi[i * ix->w + j], pa);
    }
  }
}

void WINAPI PasteIMG(HIMG im, HIMG ix, I4B x, I4B y)
{ // 揬傝晅偗
  SuperposeIMG(im, ix, x, y, foprMIX, 0);
}

void WINAPI TrimIMG(HIMG im, I4B x, I4B y, I4B w, I4B h, RGBC cb)
{ // 僩儕儈儞僌
  I4B i, j, k, l;
  HIMG ix;

  ix = CreateIMG(w, h, cb); if (!ix) return;
  for (i = 0; i < h; i++) {
    k = y + i; if (k < 0 || k >= im->h) continue;
    for (j = 0; j < w; j++) {
      l = x + j; if (l < 0 || l >= im->w) continue;
      ix->bi[i * w + j] = im->bi[k * im->w + l];
    }
  }
  MoveIMG(im, ix);
}

void WINAPI TransformIMGX(HIMG im, I4B w, I4B h, FXFM fxfm, uANY pa, RGBC cb)
{ // 帺桼曄宍
  I4B i, j, k, l, rx, ry;
  RGBC c1, c2, c3, c4;
  HIMG ix;
  F8B x, y;

  ix = CreateIMG(abs(w), abs(h), cb); if (!ix) return;
  for (i = 0; i < ix->h; i++) {
    for (j = 0; j < ix->w; j++) {
      fxfm(&x, &y, j, i, pa);
      k = (I4B)((y >= 0.0)? y: y - 1.0); if (k < -1 || k >= im->h) continue;
      l = (I4B)((x >= 0.0)? x: x - 1.0); if (l < -1 || l >= im->w) continue;
      c1 = (k >= 0        && l >= 0       )? im->bi[k * im->w + l]      : cb;
      c2 = (k >= 0        && l < im->w - 1)? im->bi[k * im->w + l+1]    : cb;
      c3 = (k < im->h - 1 && l >= 0       )? im->bi[(k+1) * im->w + l]  : cb;
      c4 = (k < im->h - 1 && l < im->w - 1)? im->bi[(k+1) * im->w + l+1]: cb;
      ry = (I4B)(255.0 * (y - k) + 0.5);
      rx = (I4B)(255.0 * (x - l) + 0.5);
      ix->bi[i * ix->w + j] = foprMIX(foprMIX(c4, c2, ry), foprMIX(c3, c1, ry), rx);
    }
  }
  MoveIMG(im, ix);
}

void WINAPI SetXFMQ(PXFMQ q, I4B x1, I4B y1, I4B x2, I4B y2, I4B x3, I4B y3, I4B x4, I4B y4)
{ // 巐嬿揰偺巜掕
  q->x1 = x1; q->y1 = y1; q->x2 = x2; q->y2 = y2; q->x3 = x3; q->y3 = y3; q->x4 = x4; q->y4 = y4;
}

void LOCALF fxfmPRS(pF8B px, pF8B py, F8B ix, F8B iy, uANY pa)
{ // 摟帇曄姺
  F8B hw, *t = (pF8B)pa;

  hw  =  t[6] * ix + t[7] * iy + 1.0;
  *px = (t[0] * ix + t[1] * iy + t[2]) / hw;
  *py = (t[3] * ix + t[4] * iy + t[5]) / hw;
}

void WINAPI TransformIMG(HIMG im, rXFMQ q, RGBC cb)
{ // 帺桼曄宍(巐嬿揰(0,0),(w-1,0),(0,h-1),(w-1,h-1)偺堏摦愭巜掕)
  I4B i, u1, u2, v1, v2, u[4], v[4];
  F8B a[8*8], b[8], t[8];

  b[0] = b[4] = 0.0;
  b[1] = b[3] = 0.0;
  b[2] = b[6] = (F8B)(im->w - 1);
  b[5] = b[7] = (F8B)(im->h - 1);
  u[0] = q->x1; v[0] = q->y1;
  u[1] = q->x2; v[1] = q->y2;
  u[2] = q->x3; v[2] = q->y3;
  u[3] = q->x4; v[3] = q->y4;
  u1 = u2 = u[0];
  v1 = v2 = v[0];
  for (i = 1; i < 4; i++) {
    if (u[i] < u1) { u1 = u[i];} else if (u[i] > u2) { u2 = u[i];}
    if (v[i] < v1) { v1 = v[i];} else if (v[i] > v2) { v2 = v[i];}
  }
  for (i = 0; i < 4; i++) {
    u[i] -= u1;
    v[i] -= v1;
  }
  a[ 0] = u[0]; a[ 1] = v[0]; a[ 2] = 1.0; a[ 3] = a[ 4] = a[ 5] = 0.0; a[ 6] = -u[0]*b[0]; a[ 7] = -v[0]*b[0];
  a[ 8] = a[ 9] = a[10] = 0.0; a[11] = u[0]; a[12] = v[0]; a[13] = 1.0; a[14] = -u[0]*b[1]; a[15] = -v[0]*b[1];
  a[16] = u[1]; a[17] = v[1]; a[18] = 1.0; a[19] = a[20] = a[21] = 0.0; a[22] = -u[1]*b[2]; a[23] = -v[1]*b[2];
  a[24] = a[25] = a[26] = 0.0; a[27] = u[1]; a[28] = v[1]; a[29] = 1.0; a[30] = -u[1]*b[3]; a[31] = -v[1]*b[3];
  a[32] = u[2]; a[33] = v[2]; a[34] = 1.0; a[35] = a[36] = a[37] = 0.0; a[38] = -u[2]*b[4]; a[39] = -v[2]*b[4];
  a[40] = a[41] = a[42] = 0.0; a[43] = u[2]; a[44] = v[2]; a[45] = 1.0; a[46] = -u[2]*b[5]; a[47] = -v[2]*b[5];
  a[48] = u[3]; a[49] = v[3]; a[50] = 1.0; a[51] = a[52] = a[53] = 0.0; a[54] = -u[3]*b[6]; a[55] = -v[3]*b[6];
  a[56] = a[57] = a[58] = 0.0; a[59] = u[3]; a[60] = v[3]; a[61] = 1.0; a[62] = -u[3]*b[7]; a[63] = -v[3]*b[7];
  if (!EquNu1d(t, a, b, 8)) { ierr(E_DAT); return;}
  TransformIMGX(im, u2 - u1 + 1, v2 - v1 + 1, fxfmPRS, (uANY)t, cb);
}

void WINAPI InvertIMG(HIMG im, I4B sw)
{ // 嬀塮斀揮
  XFMQ xfm;

  xfm.x1 = xfm.x3 = (sw & IMG_HRZ)? im->w - 1: 0;
  xfm.y1 = xfm.y2 = (sw & IMG_VRT)? im->h - 1: 0;
  xfm.x2 = xfm.x4 = (sw & IMG_HRZ)? 0: im->w - 1;
  xfm.y3 = xfm.y4 = (sw & IMG_VRT)? 0: im->h - 1;
  TransformIMG(im, &xfm, 0);
}

void WINAPI RotateIMG(HIMG im, F8B dg, RGBC cb)
{ // 擟堄妏搙夞揮(dg:搙丄斀帪寁夞傝惓)
  I4B xs, ys, xc, yc;
  F8B sn, cs;
  XFMQ xfm;

  sn = sin(dg * RPD);
  cs = cos(dg * RPD);
  xs = iround((im->w - 1) * sn);
  ys = iround((im->h - 1) * sn);
  xc = iround((im->w - 1) * cs);
  yc = iround((im->h - 1) * cs);
  SetXFMQ(&xfm, 0, 0, xc, -xs, ys, yc, xc + ys, yc - xs);
  TransformIMG(im, &xfm, cb);
}

void LOCALF ResizeIMGA(HIMG im, I4B w, I4B h)
{ // 奼戝弅彫(柺愊暯嬒朄)
  I4B i, j, k, k1, k2, l, l1, l2, m1, m2, n1, n2;
  I4B n, r, g, b, fk, fl;
  HIMG ix;

  ix = CreateIMG(abs(w), abs(h), 0); if (!ix) return;
  for (i = 0; i < ix->h; i++) {
    k1 = i * im->h / ix->h; k2 = (i + 1) * im->h / ix->h;
    m1 = i * im->h % ix->h; m2 = (i + 1) * im->h % ix->h;
    for (j = 0; j < ix->w; j++) {
      l1 = j * im->w / ix->w; l2 = (j + 1) * im->w / ix->w;
      n1 = j * im->w % ix->w; n2 = (j + 1) * im->w % ix->w;
      n = r = g = b = 0;
      for (k = k1; k < k2; k++) {
        fk = 256 * ((k < k2-1) * ix->h - (k == k1) * m1 + (k == k2-1) * m2) / ix->h;
        for (l = l1; l < l2; l++) {
          fl = fk * ((l < l2-1) * ix->w - (l == l1) * n1 + (l == l2-1) * n2) / ix->w;
          n += fl;
          r += bR(im->bi[k * im->w + l]) * fl;
          g += bG(im->bi[k * im->w + l]) * fl;
          b += bB(im->bi[k * im->w + l]) * fl;
        }
      }
      bR(ix->bi[i * ix->w + j]) = n? r / n: bR(im->bi[k1 * im->w + l1]);
      bG(ix->bi[i * ix->w + j]) = n? g / n: bG(im->bi[k1 * im->w + l1]);
      bB(ix->bi[i * ix->w + j]) = n? b / n: bB(im->bi[k1 * im->w + l1]);
    }
  }
  if (w < 0 || h < 0) { InvertIMG(ix, (w < 0) * IMG_HRZ | (h < 0) * IMG_VRT);}
  MoveIMG(im, ix);
}

void LOCALF ResizeIMGB(HIMG im, I4B w, I4B h)
{ // 奼戝弅彫(慄宍曗姰朄)
  XFMQ xfm;

  w = sign(w) * (abs(w) - 1);
  h = sign(h) * (abs(h) - 1);
  SetXFMQ(&xfm, 0, 0, w, 0, 0, h, w, h);
  TransformIMG(im, &xfm, 0);
}

void WINAPI ResizeIMGX(HIMG im, I4B w, I4B h, I4B sw)
{ // 奼戝弅彫
  if (w == 0 || h == 0) { ierr(E_PAR); return;}
  switch (sw) {
  default: _10:
    ResizeIMGA(im, w, h); break;
  case IMG_LIN: _20:
    ResizeIMGB(im, w, h); break;
  case IMG_SMO:
    if (abs(w * h) <= abs(im->w * im->h)) goto _10;  else goto _20;
  case IMG_SHA:
    if (abs(w * h) <= abs(im->w * im->h)) goto _20;  else goto _10;
  }
}

//乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗//

U4B  WINAPI BOLALGVer(void)
{ // 僶乕僕儑儞
  return MODVER;
}

BOOL WINAPI InitBOLALG(uANY pa)
{ // 奐巒張棟
  hMEM = CreatePtrList(256); if (!hMEM) return FALSE;
  return TRUE;
}

void WINAPI TermBOLALG(void)
{ // 廔椆張棟
  DeletePtrList(hMEM);
}

//乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗乗//

