static void ladmin_itemfrob_c2(dumb_ptr<block_list> bl, ItemNameId source_id, ItemNameId dest_id) { #define IFIX(v) if (v == source_id) {v = dest_id; } #define FIX(item) ladmin_itemfrob_fix_item(source_id, dest_id, &item) if (!bl) return; switch (bl->bl_type) { case BL::PC: { dumb_ptr<map_session_data> pc = bl->is_player(); for (IOff0 j : IOff0::iter()) IFIX(pc->status.inventory[j].nameid); // cart is no longer supported // IFIX(pc->status.weapon); IFIX(pc->status.shield); IFIX(pc->status.head_top); IFIX(pc->status.head_mid); IFIX(pc->status.head_bottom); Option<P<Storage>> stor_ = account2storage2(pc->status_key.account_id); if OPTION_IS_SOME(stor, stor_) { for (SOff0 j : SOff0::iter()) FIX(stor->storage_[j]); } for (IOff0 j : IOff0::iter()) { P<struct item_data> item = TRY_UNWRAP(pc->inventory_data[j], continue); if (item->nameid == source_id) { item->nameid = dest_id; if (bool(item->equip)) pc_unequipitem(pc, j, CalcStatus::NOW); item->nameid = dest_id; } } break; } case BL::MOB: { dumb_ptr<mob_data> mob = bl->is_mob(); for (Item& itm : mob->lootitemv) FIX(itm); break; } case BL::ITEM: { dumb_ptr<flooritem_data> item = bl->is_item(); FIX(item->item_data); break; } } #undef FIX #undef IFIX }
/*jpeg decode * args: * pic: pointer to picture data ( decoded image - yuyv format) * buf: pointer to input data ( compressed jpeg ) * with: picture width * height: picture height */ int jpeg_decode(uint8_t *pic, int stride, uint8_t *buf, int width, int height) { struct ctx ctx; struct jpeg_decdata *decdata; int i=0, j=0, m=0, tac=0, tdc=0; int intwidth=0, intheight=0; int mcusx=0, mcusy=0, mx=0, my=0; int ypitch=0 ,xpitch=0,x=0,y=0; int mb=0; int max[6]; ftopict convert; int err = 0; int isInitHuffman = 0; decdata = (struct jpeg_decdata*) calloc(1, sizeof(struct jpeg_decdata)); for(i=0;i<6;i++) max[i]=0; if (!decdata) { err = -1; goto error; } if (buf == NULL) { err = -1; goto error; } ctx.datap = buf; /*check SOI (0xFFD8)*/ if (getbyte(&ctx) != 0xff) { err = ERR_NO_SOI; goto error; } if (getbyte(&ctx) != M_SOI) { err = ERR_NO_SOI; goto error; } /*read tables - if exist, up to start frame marker (0xFFC0)*/ if (readtables(&ctx,M_SOF0, &isInitHuffman)) { err = ERR_BAD_TABLES; goto error; } getword(&ctx); /*header lenght*/ i = getbyte(&ctx); /*precision (8 bit)*/ if (i != 8) { err = ERR_NOT_8BIT; goto error; } intheight = getword(&ctx); /*height*/ intwidth = getword(&ctx); /*width */ if ((intheight & 7) || (intwidth & 7)) /*must be even*/ { err = ERR_BAD_WIDTH_OR_HEIGHT; goto error; } ctx.info.nc = getbyte(&ctx); /*number of components*/ if (ctx.info.nc > MAXCOMP) { err = ERR_TOO_MANY_COMPPS; goto error; } /*for each component*/ for (i = 0; i < ctx.info.nc; i++) { int h, v; ctx.comps[i].cid = getbyte(&ctx); /*component id*/ ctx.comps[i].hv = getbyte(&ctx); v = ctx.comps[i].hv & 15; /*vertical sampling */ h = ctx.comps[i].hv >> 4; /*horizontal sampling */ ctx.comps[i].tq = getbyte(&ctx); /*quantization table used*/ if (h > 3 || v > 3) { err = ERR_ILLEGAL_HV; goto error; } if (ctx.comps[i].tq > 3) { err = ERR_QUANT_TABLE_SELECTOR; goto error; } } /*read tables - if exist, up to start of scan marker (0xFFDA)*/ if (readtables(&ctx,M_SOS,&isInitHuffman)) { err = ERR_BAD_TABLES; goto error; } getword(&ctx); /* header lenght */ ctx.info.ns = getbyte(&ctx); /* number of scans */ if (!ctx.info.ns) { ALOGE("info ns %d/n",ctx.info.ns); err = ERR_NOT_YCBCR_221111; goto error; } /*for each scan*/ for (i = 0; i < ctx.info.ns; i++) { ctx.dscans[i].cid = getbyte(&ctx); /*component id*/ tdc = getbyte(&ctx); tac = tdc & 15; /*ac table*/ tdc >>= 4; /*dc table*/ if (tdc > 1 || tac > 1) { err = ERR_QUANT_TABLE_SELECTOR; goto error; } for (j = 0; j < ctx.info.nc; j++) if (ctx.comps[j].cid == ctx.dscans[i].cid) break; if (j == ctx.info.nc) { err = ERR_UNKNOWN_CID_IN_SCAN; goto error; } ctx.dscans[i].hv = ctx.comps[j].hv; ctx.dscans[i].tq = ctx.comps[j].tq; ctx.dscans[i].hudc.dhuff = dec_huffdc + tdc; ctx.dscans[i].huac.dhuff = dec_huffac + tac; } i = getbyte(&ctx); /*0 */ j = getbyte(&ctx); /*63*/ m = getbyte(&ctx); /*0 */ if (i != 0 || j != 63 || m != 0) { ALOGE("hmm FW error,not seq DCT ??\n"); } /*build huffman tables*/ if(!isInitHuffman) { if(huffman_init(&ctx) < 0) return -ERR_BAD_TABLES; } /* if (ctx->dscans[0].cid != 1 || ctx->dscans[1].cid != 2 || ctx->dscans[2].cid != 3) { err = ERR_NOT_YCBCR_221111; goto error; } if (ctx->dscans[1].hv != 0x11 || ctx->dscans[2].hv != 0x11) { err = ERR_NOT_YCBCR_221111; goto error; } */ /* if internal width and external are not the same or heigth too and pic not allocated realloc the good size and mark the change need 1 macroblock line more ?? */ if (intwidth > width || intheight > height) { return -ERR_BAD_WIDTH_OR_HEIGHT; #if 0 width = intwidth; height = intheight; // BytesperPixel 2 yuyv , 3 rgb24 *pic = (uint8_t*) realloc( *pic, intwidth * (intheight + 8) * 2); #endif } switch (ctx.dscans[0].hv) { case 0x22: // 411 mb=6; mcusx = width >> 4; mcusy = height >> 4; xpitch = 16 * 2; ypitch = 16 * stride; convert = yuv420pto422; //choose the right conversion function break; case 0x21: //422 mb=4; mcusx = width >> 4; mcusy = height >> 3; xpitch = 16 * 2; ypitch = 8 * stride; convert = yuv422pto422; //choose the right conversion function break; case 0x11: //444 mcusx = width >> 3; mcusy = height >> 3; xpitch = 8 * 2; ypitch = 8 * stride; if (ctx.info.ns==1) { mb = 1; convert = yuv400pto422; //choose the right conversion function } else { mb=3; convert = yuv444pto422; //choose the right conversion function } break; default: err = ERR_NOT_YCBCR_221111; goto error; break; } idctqtab(ctx.quant[ctx.dscans[0].tq], decdata->dquant[0]); idctqtab(ctx.quant[ctx.dscans[1].tq], decdata->dquant[1]); idctqtab(ctx.quant[ctx.dscans[2].tq], decdata->dquant[2]); setinput(&ctx.in, ctx.datap); dec_initscans(&ctx); ctx.dscans[0].next = 2; ctx.dscans[1].next = 1; ctx.dscans[2].next = 0; /* 4xx encoding */ for (my = 0,y=0; my < mcusy; my++,y+=ypitch) { for (mx = 0,x=0; mx < mcusx; mx++,x+=xpitch) { if (ctx.info.dri && !--ctx.info.nm) if (dec_checkmarker(&ctx)) { err = ERR_WRONG_MARKER; goto error; } switch (mb) { case 6: decode_mcus(&ctx.in, decdata->dcts, mb, ctx.dscans, max); idct(decdata->dcts, decdata->out, decdata->dquant[0], IFIX(128.5), max[0]); idct(decdata->dcts + 64, decdata->out + 64, decdata->dquant[0], IFIX(128.5), max[1]); idct(decdata->dcts + 128, decdata->out + 128, decdata->dquant[0], IFIX(128.5), max[2]); idct(decdata->dcts + 192, decdata->out + 192, decdata->dquant[0], IFIX(128.5), max[3]); idct(decdata->dcts + 256, decdata->out + 256, decdata->dquant[1], IFIX(0.5), max[4]); idct(decdata->dcts + 320, decdata->out + 320, decdata->dquant[2], IFIX(0.5), max[5]); break; case 4: decode_mcus(&ctx.in, decdata->dcts, mb, ctx.dscans, max); idct(decdata->dcts, decdata->out, decdata->dquant[0], IFIX(128.5), max[0]); idct(decdata->dcts + 64, decdata->out + 64, decdata->dquant[0], IFIX(128.5), max[1]); idct(decdata->dcts + 128, decdata->out + 256, decdata->dquant[1], IFIX(0.5), max[4]); idct(decdata->dcts + 192, decdata->out + 320, decdata->dquant[2], IFIX(0.5), max[5]); break; case 3: decode_mcus(&ctx.in, decdata->dcts, mb, ctx.dscans, max); idct(decdata->dcts, decdata->out, decdata->dquant[0], IFIX(128.5), max[0]); idct(decdata->dcts + 64, decdata->out + 256, decdata->dquant[1], IFIX(0.5), max[4]); idct(decdata->dcts + 128, decdata->out + 320, decdata->dquant[2], IFIX(0.5), max[5]); break; case 1: decode_mcus(&ctx.in, decdata->dcts, mb, ctx.dscans, max); idct(decdata->dcts, decdata->out, decdata->dquant[0], IFIX(128.5), max[0]); break; } // switch enc411 convert(decdata->out,pic+y+x,stride); //convert to 422 } } m = dec_readmarker(&ctx.in); if (m != M_EOI) { err = ERR_NO_EOI; goto error; } free(decdata); return 0; error: free(decdata); return err; }
void ByteHomo (ByteImage *srcBuf, ByteImage *destBuf, double a, double b, double c, double d, double e, double f, double m, double n, double p) { unsigned char *dest, *src; double acm, bcn, dfm, efn, dnm, det, xNom, yNom, Denom; double h11, h12, h13, h21, h22, h23, h31, h32, h33; double xh[4], yh[4], z, tmp; double xstartF, xendF; double srcXf, srcYf; double angle, minAngle; int tmpInt; int yend, ystart, xstartI, xendI, destX, destY, srcXi, srcYi; int x, y, p00, p01, p10, p11; int w, h; int order[4], startNextOrder, endNextOrder; int i, j, best, region, startP, startQ, endP, endQ, delta, minj; int h11Fixed, h21Fixed, h31Fixed, xNomFixed, yNomFixed, DenomFixed; int srcXfixed, srcYfixed, p00Fixed, p01Fixed; /* make compiler happy */ startNextOrder = endNextOrder = startP = startQ = endP = endQ = minj = 0; /* * Calculate where the source rectangle lands on the destination image. * These will be four coordinates, xh[0]..xh[3], yh[0]..yh[3]. */ w = srcBuf->width-1; h = srcBuf->height-1; z = m * 0 + n * 0 + p; xh[0] = (a * 0 + b * 0 + c) / z; yh[0] = (d * 0 + e * 0 + f) / z; z = m * w + n * 0 + p; xh[1] = (a * w + b * 0 + c) / z; yh[1] = (d * w + e * 0 + f) / z; z = m * 0 + n * h + p; xh[2] = (a * 0 + b * h + c) / z; yh[2] = d * 0 + e * h + f; z = m * w + n * h + p; xh[3] = (a * w + b * h + c) / z; yh[3] = (d * w + e * h + f) / z; /* * calculate all the entries in the inverse matrix H */ acm = a*p -c*m; bcn = b*p -c*n; dnm = d*n - e*m; dfm = d*p - f*m; efn = e*p - f*n; det = a * efn - b * dfm + c*dnm; h11 = efn / det; h12 = -bcn / det; h21 = -dfm / det; h22 = acm / det; h13 = (b*f - e*c)/ det; h23 = -(a*f - d*c)/det; h31 = dnm / det; h32 = -(a*n - b*m)/det; h33 = (a*e - b*d)/det; h11Fixed = FIX(h11); h21Fixed = FIX(h21); h31Fixed = FIX(h31); /* * Sort these 4 coordinates first by y coordinate, then by * x coordinate */ for (i=0; i<4; i++) { best = i; for (j=i+1; j<4; j++) { if ((yh[j] < yh[best]) || ((yh[j] == yh[best]) && (xh[j] < xh[best]))) { best = j; } } tmp = xh[i]; xh[i] = xh[best]; xh[best] = tmp; tmp = yh[i]; yh[i] = yh[best]; yh[best] = tmp; } /* * find the anti-clockwise order of the points * start from (x[order[0]], y[order[0]] * where (x[order[i+1]], y[order[i+1]]) is the next point of * (x[order[i]], y[order[i]]) in anti-clockwise direction */ for (i=0; i<4; i++) { order[i] = i; } for (i=1; i<4; i++) { minAngle = 2*M_PI; /* starting from the horizontal line on the left of point(order[i-1]), * rotating the line anti-clockwise, * the first point being swept thru is the next point in * anticlockwise direction */ for (j=i; j<4; j++) { /* angle = anticlockwise angle from * the horizontal line on the left of point(order[i-1]) to * the line thru point(order[i-1]), point(order[j]) */ angle = M_PI - atan2(yh[order[j]] - yh[order[i-1]], xh[order[j]] - xh[order[i-1]]); if (angle < minAngle) { minAngle = angle; minj = j; } } tmpInt = order[i]; order[i] = order[minj]; order[minj] = tmpInt; } /* * We now have the coordinates to the quadrilateral that the * src image maps into on the destination image. x[0],y[0] is * the top, x[3],y[3] is the bottom. Divide it up into 3 regions: * the top (y[0]..y[1]), the middle (y[1]..y[2]) and the bottom * (y[2]..y[3]). For each region, calculate the starting and * ending x coordinates for scanline y on the destination image. * These are the only pixels in the destination that are affected. */ for (region=0; region<3; region++) { if (region == 0) { startNextOrder = 1; endNextOrder = 3; startP = 0; startQ = order[1]; endP = 0; endQ = order[3]; } else { if (yh[startQ] > yh[endQ]) { endP = endQ; endQ = order[--endNextOrder]; } else { startP = startQ; startQ = order[++startNextOrder]; } } ystart = max(0, (int)floor(yh[region])); yend = min(destBuf->height, (int)yh[region+1]); for (destY=ystart; destY < yend; destY++) { /* * We're working on scanline destY. Compute the starting and * ending x coordinates (xstart, xend) on the destination * image of the region for which source pixels are defined. * xstart is given by the x coordinate of the line from * (x[startP], y[startP]) to x(x[startQ], y[startQ]) with * y coordinate destY. * xend is similarly computed from x/y[endP/endQ] * The starting coordinate is rounded down, the ending coordinate * rounded up. */ xstartF = xh[startP] + (destY-yh[startP])*(xh[startQ]-xh[startP])/ (yh[startQ]-yh[startP]); xendF = xh[endP] + (destY-yh[endP])*(xh[endQ]-xh[endP])/(yh[endQ]-yh[endP]); xstartF = max (0, xstartF); xendF = min (xendF, destBuf->width); xstartI = (int)ceil(xstartF); xendI = (int)(xendF); dest = destBuf->firstByte + (destY*destBuf->parentWidth + xstartI); /* * H is the inverse homogeneous matrix which maps destination points * back to source image * H(x,y,1) = (xNom, yNom, Denom) * srcX = xNom/Denom * srcY = yNom/Denom */ xNom = h11 * xstartI + h12 * destY + h13; yNom = h21 * xstartI + h22 * destY + h23; Denom = h31 * xstartI + h32 * destY + h33; xNomFixed = FIX(xNom); yNomFixed = FIX(yNom); DenomFixed = FIX(Denom); srcXf = xNom / Denom; srcYf = yNom / Denom; srcXfixed = FIX(srcXf); srcYfixed = FIX(srcYf); for (destX = xstartI; destX < xendI; destX++, dest++) { /* * The following code computes the value of a pixel in * the destination image at (destX, destY). It has been * optimized by using fixed point arithmetic (see macro.h * for a description of the fixed point operators). * src[XY]fixed are the fixed-point coordinates of the * corresponding location in the source image. We compute * the integer (truncated) value of that location in src[XY]i, * and the remainder in x and y. p00..p11 are the four closest * pixels to src[XY], and we use them in the bilinear * interpolation routine. On a Pentium 266, this routine will * process about 2.02 Mpix/sec. For comparison, 320x240 * video at 30 fps is 2.3 Mpix/sec */ srcXi = IUNFIX(srcXfixed); srcYi = IUNFIX(srcYfixed); if ((srcXi >= 0) && (srcXi <= w) && (srcYi >= 0) && (srcYi <= h)) { src = srcBuf->firstByte + (srcYi*srcBuf->parentWidth + srcXi); x = srcXfixed - IFIX(srcXi); y = srcYfixed - IFIX(srcYi); p00 = *src++; p10 = *src; src += srcBuf->parentWidth; p11 = *src--; p01 = *src; p00Fixed = IFIX(p00) + x*(p10-p00); p01Fixed = IFIX(p01) + x*(p11-p01); delta = IUNFIX_ROUND(p01Fixed - p00Fixed); p00Fixed = p00Fixed + y*delta; *dest = IUNFIX_ROUND(p00Fixed); } /* * update the srcX, srcY * H(x+1,y,1) = (xNom+h11, yNom+h21, Denom+h31) */ xNomFixed += h11Fixed; yNomFixed += h21Fixed; DenomFixed += h31Fixed; srcXfixed = FIXDIV(xNomFixed, DenomFixed); srcYfixed = FIXDIV(yNomFixed, DenomFixed); } } } }