static void gd_loadimage_cairo(GVJ_t * job, usershape_t *us, boxf b, boolean filled) { cairo_t *cr = (cairo_t *) job->context; /* target context */ unsigned int x, y, stride, width, height, px; unsigned char *data; cairo_surface_t *surface; /* source surface */ gdImagePtr im; if ((im = gd_loadimage(job, us))) { width = im->sx; height = im->sy; // cairo_format_stride_for_width() not available prior to cairo-1.6.4 or so (fc9) //stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, width); stride = width*4; data = malloc (stride * height); surface = cairo_image_surface_create_for_data (data, CAIRO_FORMAT_ARGB32, width, height, stride); if (im->trueColor) { for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { px = gdImageTrueColorPixel(im, x, y); *data++ = gdTrueColorGetBlue(px); *data++ = gdTrueColorGetGreen(px); *data++ = gdTrueColorGetRed(px); *data++ = (0x7F-gdTrueColorGetAlpha(px)) << 1; } } } else { for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { px = gdImagePalettePixel(im, x, y); *data++ = im->blue[px]; *data++ = im->green[px]; *data++ = im->red[px]; *data++ = (px==im->transparent)?0x00:0xff; } } } cairo_save(cr); cairo_translate(cr, (b.LL.x + (b.UR.x - b.LL.x) * (1. - (job->dpi.x) / 96.) / 2.), (-b.UR.y + (b.UR.y - b.LL.y) * (1. - (job->dpi.y) / 96.) / 2.)); cairo_scale(cr, ((b.UR.x - b.LL.x) * (job->dpi.x) / (96. * us->w)), ((b.UR.y - b.LL.y) * (job->dpi.y) / (96. * us->h))); cairo_set_source_surface (cr, surface, 0, 0); cairo_paint (cr); cairo_restore(cr); cairo_surface_destroy(surface); } }
/* bring the palette colors in im2 to be closer to im1 * */ int gdImageColorMatch (gdImagePtr im1, gdImagePtr im2) { unsigned long *buf; /* stores our calculations */ unsigned long *bp; /* buf ptr */ int color, rgb; int x,y; int count; if( !im1->trueColor ) { return -1; /* im1 must be True Color */ } if( im2->trueColor ) { return -2; /* im2 must be indexed */ } if( (im1->sx != im2->sx) || (im1->sy != im2->sy) ) { return -3; /* the images are meant to be the same dimensions */ } if (im2->colorsTotal<1) { return -4; /* At least 1 color must be allocated */ } buf = (unsigned long *)safe_emalloc(sizeof(unsigned long), 5 * im2->colorsTotal, 0); memset( buf, 0, sizeof(unsigned long) * 5 * im2->colorsTotal ); for (x=0; x<im1->sx; x++) { for( y=0; y<im1->sy; y++ ) { color = im2->pixels[y][x]; rgb = im1->tpixels[y][x]; bp = buf + (color * 5); (*(bp++))++; *(bp++) += gdTrueColorGetRed(rgb); *(bp++) += gdTrueColorGetGreen(rgb); *(bp++) += gdTrueColorGetBlue(rgb); *(bp++) += gdTrueColorGetAlpha(rgb); } } bp = buf; for (color=0; color<im2->colorsTotal; color++) { count = *(bp++); if( count > 0 ) { im2->red[color] = *(bp++) / count; im2->green[color] = *(bp++) / count; im2->blue[color] = *(bp++) / count; im2->alpha[color] = *(bp++) / count; } else { bp += 4; } } gdFree(buf); return 0; }
void Texture::init() { glGenTextures(1, &tid); glBindTexture(GL_TEXTURE_2D, tid); int datSize = w*h*4; // unsigned char data[datSize]; unsigned char* data = new unsigned char[datSize]; for(int j=0; j<h; j++) for(int i=0; i<w; i++) { // gdTrueColor* are in gd.h (ARGB - alpha is 7-bit) int key = (j*w+i)*4; data[key] = gdTrueColorGetRed(im->tpixels[h-1-j][i]); data[key+1] = gdTrueColorGetGreen(im->tpixels[h-1-j][i]); data[key+2] = gdTrueColorGetBlue(im->tpixels[h-1-j][i]); data[key+3] = (127 - gdTrueColorGetAlpha(im->tpixels[h-1-j][i]))<<1; } // well, knowing that textures are at most medium size, // just use auto-mipmap generation. we actually don't have to // be bothered by power-of-two issues. gluBuild2DMipmaps(GL_TEXTURE_2D, 4, w, h, GL_RGBA, GL_UNSIGNED_BYTE, data); // glTexImage2D(GL_TEXTURE_2D, 0, 4, wpo2, hpo2, 0, GL_RGBA, // GL_UNSIGNED_BYTE, data); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); if(im) gdImageDestroy(im); delete data; }
/** * Based on libgd/gd_topal.c */ static void ngx_pngquant_convert_gd_pixel_to_rgba(liq_color output_row[], int y, int width, void *userinfo) { gdImagePtr oim = userinfo; int x; for(x = 0; x < width; x++) { output_row[x].r = gdTrueColorGetRed(oim->tpixels[y][x]) * 255/gdRedMax; output_row[x].g = gdTrueColorGetGreen(oim->tpixels[y][x]) * 255/gdGreenMax; output_row[x].b = gdTrueColorGetBlue(oim->tpixels[y][x]) * 255/gdBlueMax; int alpha = gdTrueColorGetAlpha(oim->tpixels[y][x]); if (gdAlphaOpaque < gdAlphaTransparent) { alpha = gdAlphaTransparent - alpha; } output_row[x].a = alpha * 255/gdAlphaMax; } }
/* Compare two buffers, returning the number of pixels that are * different and the maximum difference of any single color channel in * result_ret. * * This function should be rewritten to compare all formats supported by * cairo_format_t instead of taking a mask as a parameter. */ void gdTestImageDiff(gdImagePtr buf_a, gdImagePtr buf_b, gdImagePtr buf_diff, CuTestImageResult *result_ret) { int x, y; int c1, c2; for (y = 0; y < gdImageSY(buf_a); y++) { for (x = 0; x < gdImageSX(buf_a); x++) { c1 = gdImageGetTrueColorPixel(buf_a, x, y); c2 = gdImageGetTrueColorPixel(buf_b, x, y); /* check if the pixels are the same */ if (c1 != c2) { int r1,b1,g1,a1,r2,b2,g2,a2; unsigned int diff_a,diff_r,diff_g,diff_b; a1 = gdTrueColorGetAlpha(c1); a2 = gdTrueColorGetAlpha(c2); diff_a = abs (a1 - a2); diff_a *= 4; /* emphasize */ if (diff_a) { diff_a += 128; /* make sure it's visible */ } if (diff_a > gdAlphaMax) { diff_a = gdAlphaMax/2; } r1 = gdTrueColorGetRed(c1); r2 = gdTrueColorGetRed(c2); diff_r = abs (r1 - r2); /* diff_r *= 4; /* emphasize */ if (diff_r) { diff_r += gdRedMax/2; /* make sure it's visible */ } if (diff_r > 255) { diff_r = 255; } g1 = gdTrueColorGetGreen(c1); g2 = gdTrueColorGetGreen(c2); diff_g = abs (g1 - g2); diff_g *= 4; /* emphasize */ if (diff_g) { diff_g += gdGreenMax/2; /* make sure it's visible */ } if (diff_g > 255) { diff_g = 255; } b1 = gdTrueColorGetBlue(c1); b2 = gdTrueColorGetBlue(c2); diff_b = abs (b1 - b2); diff_b *= 4; /* emphasize */ if (diff_b) { diff_b += gdBlueMax/2; /* make sure it's visible */ } if (diff_b > 255) { diff_b = 255; } result_ret->pixels_changed++; if (buf_diff) gdImageSetPixel(buf_diff, x,y, gdTrueColorAlpha(diff_r, diff_g, diff_b, diff_a)); } else { if (buf_diff) gdImageSetPixel(buf_diff, x,y, gdTrueColorAlpha(255,255,255,0)); } } } }
static void _gdImageGd2 (gdImagePtr im, gdIOCtx * out, int cs, int fmt) { int ncx, ncy, cx, cy; int x, y, ylo, yhi, xlo, xhi; int chunkLen; int chunkNum = 0; char *chunkData = NULL; /* So we can gdFree it with impunity. */ char *compData = NULL; /* So we can gdFree it with impunity. */ uLongf compLen; int idxPos = 0; int idxSize; t_chunk_info *chunkIdx = NULL; int posSave; int bytesPerPixel = im->trueColor ? 4 : 1; int compMax = 0; /*printf("Trying to write GD2 file\n"); */ /* */ /* Force fmt to a valid value since we don't return anything. */ /* */ if ((fmt != GD2_FMT_RAW) && (fmt != GD2_FMT_COMPRESSED)) { fmt = im->trueColor ? GD2_FMT_TRUECOLOR_COMPRESSED : GD2_FMT_COMPRESSED; }; if (im->trueColor) { fmt += 2; } /* */ /* Make sure chunk size is valid. These are arbitrary values; 64 because it seems */ /* a little silly to expect performance improvements on a 64x64 bit scale, and */ /* 4096 because we buffer one chunk, and a 16MB buffer seems a little large - it may be */ /* OK for one user, but for another to read it, they require the buffer. */ /* */ if (cs == 0) { cs = GD2_CHUNKSIZE; } else if (cs < GD2_CHUNKSIZE_MIN) { cs = GD2_CHUNKSIZE_MIN; } else if (cs > GD2_CHUNKSIZE_MAX) { cs = GD2_CHUNKSIZE_MAX; }; /* Work out number of chunks. */ ncx = im->sx / cs + 1; ncy = im->sy / cs + 1; /* Write the standard header. */ _gd2PutHeader (im, out, cs, fmt, ncx, ncy); if (gd2_compressed (fmt)) { /* */ /* Work out size of buffer for compressed data, If CHUNKSIZE is large, */ /* then these will be large! */ /* */ /* The zlib notes say output buffer size should be (input size) * 1.01 * 12 */ /* - we'll use 1.02 to be paranoid. */ /* */ compMax = cs * bytesPerPixel * cs * 1.02 + 12; /* */ /* Allocate the buffers. */ /* */ chunkData = gdCalloc (cs * bytesPerPixel * cs, 1); if (!chunkData) { goto fail; } compData = gdCalloc (compMax, 1); if (!compData) { goto fail; } /* */ /* Save the file position of chunk index, and allocate enough space for */ /* each chunk_info block . */ /* */ idxPos = gdTell (out); idxSize = ncx * ncy * sizeof (t_chunk_info); GD2_DBG (printf ("Index size is %d\n", idxSize)); gdSeek (out, idxPos + idxSize); chunkIdx = gdCalloc (idxSize * sizeof (t_chunk_info), 1); if (!chunkIdx) { goto fail; } }; _gdPutColors (im, out); GD2_DBG (printf ("Size: %dx%d\n", im->sx, im->sy)); GD2_DBG (printf ("Chunks: %dx%d\n", ncx, ncy)); for (cy = 0; (cy < ncy); cy++) { for (cx = 0; (cx < ncx); cx++) { ylo = cy * cs; yhi = ylo + cs; if (yhi > im->sy) { yhi = im->sy; }; GD2_DBG (printf ("Processing Chunk (%dx%d), y from %d to %d\n", cx, cy, ylo, yhi)); chunkLen = 0; for (y = ylo; (y < yhi); y++) { /*GD2_DBG(printf("y=%d: ",y)); */ xlo = cx * cs; xhi = xlo + cs; if (xhi > im->sx) { xhi = im->sx; }; if (gd2_compressed (fmt)) { for (x = xlo; x < xhi; x++) { /* 2.0.11: use truecolor pixel array. TBB */ /*GD2_DBG(printf("%d...",x)); */ if (im->trueColor) { int p = im->tpixels[y][x]; chunkData[chunkLen++] = gdTrueColorGetAlpha (p); chunkData[chunkLen++] = gdTrueColorGetRed (p); chunkData[chunkLen++] = gdTrueColorGetGreen (p); chunkData[chunkLen++] = gdTrueColorGetBlue (p); } else { int p = im->pixels[y][x]; chunkData[chunkLen++] = p; } }; } else { for (x = xlo; x < xhi; x++) { /*GD2_DBG(printf("%d, ",x)); */ if (im->trueColor) { gdPutInt (im->tpixels[y][x], out); } else { gdPutC ((unsigned char) im->pixels[y][x], out); } }; }; /*GD2_DBG(printf("y=%d done.\n",y)); */ }; if (gd2_compressed (fmt)) { compLen = compMax; if (compress ((unsigned char *) &compData[0], &compLen, (unsigned char *) &chunkData[0], chunkLen) != Z_OK) { printf ("Error from compressing\n"); } else { chunkIdx[chunkNum].offset = gdTell (out); chunkIdx[chunkNum++].size = compLen; GD2_DBG (printf ("Chunk %d size %d offset %d\n", chunkNum, chunkIdx[chunkNum - 1].size, chunkIdx[chunkNum - 1].offset)); if (gdPutBuf (compData, compLen, out) <= 0) { fprintf(stderr, "gd write error\n"); }; }; }; }; }; if (gd2_compressed (fmt)) { /* Save the position, write the index, restore position (paranoia). */ GD2_DBG (printf ("Seeking %d to write index\n", idxPos)); posSave = gdTell (out); gdSeek (out, idxPos); GD2_DBG (printf ("Writing index\n")); for (x = 0; x < chunkNum; x++) { GD2_DBG (printf ("Chunk %d size %d offset %d\n", x, chunkIdx[x].size, chunkIdx[x].offset)); gdPutInt (chunkIdx[x].offset, out); gdPutInt (chunkIdx[x].size, out); }; /* We don't use fwrite for *endian reasons. */ /*fwrite(chunkIdx, sizeof(int)*2, chunkNum, out); */ gdSeek (out, posSave); }; /*printf("Memory block size is %d\n",gdTell(out)); */ fail: GD2_DBG (printf ("Freeing memory\n")); if (chunkData) { gdFree (chunkData); } if (compData) { gdFree (compData); } if (chunkIdx) { gdFree (chunkIdx); } GD2_DBG (printf ("Done\n")); }
void gdImageCopyResampled (uint8_t *dst, uint8_t *src, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH) { int x, y; double sy1, sy2, sx1, sx2; for (y = dstY; (y < dstY + dstH); y++) { sy1 = ((double) y - (double) dstY) * (double) srcH / (double) dstH; sy2 = ((double) (y + 1) - (double) dstY) * (double) srcH / (double) dstH; for (x = dstX; (x < dstX + dstW); x++) { double sx, sy; double spixels = 0; double red = 0.0, green = 0.0, blue = 0.0, alpha = 0.0; sx1 = ((double) x - (double) dstX) * (double) srcW / dstW; sx2 = ((double) (x + 1) - (double) dstX) * (double) srcW / dstW; sy = sy1; do { double yportion; if (floor2 (sy) == floor2 (sy1)) { yportion = 1.0 - (sy - (double)floor2 (sy)); if (yportion > sy2 - sy1) { yportion = sy2 - sy1; } sy = (double)floor2 (sy); } else if (sy == floor2 (sy2)) { yportion = sy2 - (double)floor2 (sy2); } else { yportion = 1.0; } sx = sx1; do { double xportion; double pcontribution; int p; if (floor2 (sx) == floor2 (sx1)) { xportion = 1.0 - (sx - (double)floor2 (sx)); if (xportion > sx2 - sx1) { xportion = sx2 - sx1; } sx = (double)floor2 (sx); } else if (sx == floor2 (sx2)) { xportion = sx2 - (double)floor2 (sx2); } else { xportion = 1.0; } pcontribution = xportion * yportion; /* 2.08: previously srcX and srcY were ignored. Andrew Pattison */ p = gdImageGetTrueColorPixel (src, (int) sx + srcX, (int) sy + srcY, srcW); red += gdTrueColorGetRed (p) * pcontribution; green += gdTrueColorGetGreen (p) * pcontribution; blue += gdTrueColorGetBlue (p) * pcontribution; alpha += gdTrueColorGetAlpha (p) * pcontribution; spixels += xportion * yportion; sx += 1.0; } while (sx < sx2); sy += 1.0; } while (sy < sy2); if (spixels != 0.0) { red /= spixels; green /= spixels; blue /= spixels; alpha /= spixels; } /* Clamping to allow for rounding errors above */ if (red > 255.0) { red = 255.0; } if (green > 255.0) { green = 255.0; } if (blue > 255.0) { blue = 255.0; } if (alpha > gdAlphaMax) { alpha = gdAlphaMax; } gdImageSetPixel (dst, x, y, gdTrueColorAlpha ((int) red, (int) green, (int) blue, (int) alpha), dstW); } } }