unsigned char * color_average_resize(unsigned char * orgin, int ox, int oy, int dx, int dy, int rotate) { eDebug("picviewer: color_average_resize: buf=%lx oxy=%d,%d dxy=%d,%d rotate=%d", orgin, ox, oy, dx, dy, rotate); unsigned char *cr, *p, *q; int i, j, k, l, xa, xb, ya, yb; int sq, r, g, b; cr = new unsigned char[dx * dy * 3]; if (cr == NULL) { eDebug("picviewer: color_average_resize: Error: malloc"); return orgin; } p = cr; for (j = 0; j < dy; j++) { for (i = 0; i < dx; i++, p += 3) { xa = i * ox / dx; ya = j * oy / dy; xb = (i + 1) * ox / dx; if (xb >= ox) xb = ox - 1; yb = (j + 1) * oy / dy; if (yb >= oy) yb = oy - 1; for (l = ya, r = 0, g = 0, b = 0, sq = 0; l <= yb; l++) { q = orgin + ((l * ox + xa) * 3); for (k = xa; k <= xb; k++, q += 3, sq++) { r += q[0]; g += q[1]; b += q[2]; } } p[0] = r / sq; p[1] = g / sq; p[2] = b / sq; } } if (rotate) { unsigned char *rot; rot = simple_rotate(cr, dx, dy, rotate); if (rot != cr && rot != NULL) { // rotate() managed to do something... delete [] cr; cr = rot; } } // eDebug("picviewer: color_average_resize done"); return cr; }
static int filter_slice(RotContext *rot, ThreadData *td, int job, int nb_jobs) { AVFrame *in = td->in; AVFrame *out = td->out; const int outw = td->outw, outh = td->outh; const int inw = td->inw, inh = td->inh; const int plane = td->plane; const int xi = td->xi, yi = td->yi; const int c = td->c, s = td->s; const int start = (outh * job ) / nb_jobs; const int end = (outh * (job+1)) / nb_jobs; int xprime = td->xprime + start * s; int yprime = td->yprime + start * c; int i, j, x, y; for (j = start; j < end; j++) { x = xprime + xi + FIXP*(inw-1)/2; y = yprime + yi + FIXP*(inh-1)/2; if (fabs(rot->angle - 0) < FLT_EPSILON && outw == inw && outh == inh) { simple_rotate(out->data[plane] + j * out->linesize[plane], in->data[plane] + j * in->linesize[plane], in->linesize[plane], 0, rot->draw.pixelstep[plane], outw); } else if (fabs(rot->angle - M_PI/2) < FLT_EPSILON && outw == inh && outh == inw) { simple_rotate(out->data[plane] + j * out->linesize[plane], in->data[plane] + j * rot->draw.pixelstep[plane], in->linesize[plane], 1, rot->draw.pixelstep[plane], outw); } else if (fabs(rot->angle - M_PI) < FLT_EPSILON && outw == inw && outh == inh) { simple_rotate(out->data[plane] + j * out->linesize[plane], in->data[plane] + (outh-j-1) * in->linesize[plane], in->linesize[plane], 2, rot->draw.pixelstep[plane], outw); } else if (fabs(rot->angle - 3*M_PI/2) < FLT_EPSILON && outw == inh && outh == inw) { simple_rotate(out->data[plane] + j * out->linesize[plane], in->data[plane] + (outh-j-1) * rot->draw.pixelstep[plane], in->linesize[plane], 3, rot->draw.pixelstep[plane], outw); } else { for (i = 0; i < outw; i++) { int32_t v; int x1, y1; uint8_t *pin, *pout; x1 = x>>16; y1 = y>>16; /* the out-of-range values avoid border artifacts */ if (x1 >= -1 && x1 <= inw && y1 >= -1 && y1 <= inh) { uint8_t inp_inv[4]; /* interpolated input value */ pout = out->data[plane] + j * out->linesize[plane] + i * rot->draw.pixelstep[plane]; if (rot->use_bilinear) { pin = rot->interpolate_bilinear(inp_inv, in->data[plane], in->linesize[plane], rot->draw.pixelstep[plane], x, y, inw-1, inh-1); } else { int x2 = av_clip(x1, 0, inw-1); int y2 = av_clip(y1, 0, inh-1); pin = in->data[plane] + y2 * in->linesize[plane] + x2 * rot->draw.pixelstep[plane]; } switch (rot->draw.pixelstep[plane]) { case 1: *pout = *pin; break; case 2: v = AV_RL16(pin); AV_WL16(pout, v); break; case 3: v = AV_RB24(pin); AV_WB24(pout, v); break; case 4: *((uint32_t *)pout) = *((uint32_t *)pin); break; default: memcpy(pout, pin, rot->draw.pixelstep[plane]); break; } } x += c; y -= s; } } xprime += s; yprime += c; } return 0; }