result_t Image::set_progressive(bool newVal) { if (!m_image) return CHECK_ERROR(CALL_E_INVALID_CALL); gdImageInterlace(m_image, newVal); return 0; }
JBoolean SetInterlace ( gdImagePtr image, const LaceOption interlace ) { if (interlace != kIgnoreInterlace) { gdImageInterlace(image, interlace); return kJTrue; } else { return kJFalse; } }
// Prints the error string if in debug, otherwise generates an error image void Error(const char *pcText) { if (g_oCGI.Debug()) { printf("Error: %s\n\n", pcText); printf("Usage: id=<counter_id> [font=<font_name>] [digits=<num_of_digits>]\n"); printf("Note: out.gif will be placed in %s\n", COUNTER_ROOT); } else { gdImagePtr pOutImg = NULL; pOutImg = gdImageCreate(20, 20); if (pOutImg) { int iBlack = gdImageColorAllocate(pOutImg, 0, 0, 0); int iRed = gdImageColorAllocate(pOutImg, 255, 0, 0); gdImageFill(pOutImg, 0, 0, iBlack); gdImageLine(pOutImg, 0, 0, 19, 19, iRed); gdImageLine(pOutImg, 19, 0, 0, 19, iRed); gdImageInterlace(pOutImg, 1); #ifdef WIN32 _setmode(_fileno(stdout), _O_BINARY); #endif printf("Content-type: image/gif\n\n"); gdImageGif(pOutImg, stdout); } } } // Error
BGD_DECLARE(gdImagePtr) gdImageCreateFromJpegCtxEx(gdIOCtx *infile, int ignore_warning) { struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; jmpbuf_wrapper jmpbufw; /* volatile so we can gdFree them after longjmp */ volatile JSAMPROW row = 0; volatile gdImagePtr im = 0; JSAMPROW rowptr[1]; JDIMENSION i, j; int retval; JDIMENSION nrows; int channels = 3; int inverted = 0; #ifdef JPEG_DEBUG gd_error_ex(GD_DEBUG, "gd-jpeg: gd JPEG version %s\n", GD_JPEG_VERSION); gd_error_ex(GD_DEBUG, "gd-jpeg: JPEG library version %d, %d-bit sample values\n", JPEG_LIB_VERSION, BITS_IN_JSAMPLE); gd_error_ex(GD_DEBUG, "sizeof: %d\n", sizeof(struct jpeg_decompress_struct)); #endif memset(&cinfo, 0, sizeof(cinfo)); memset(&jerr, 0, sizeof(jerr)); jmpbufw.ignore_warning = ignore_warning; cinfo.err = jpeg_std_error(&jerr); cinfo.client_data = &jmpbufw; cinfo.err->emit_message = jpeg_emit_message; if(setjmp(jmpbufw.jmpbuf) != 0) { /* we're here courtesy of longjmp */ if(row) { gdFree(row); } if(im) { gdImageDestroy(im); } return 0; } cinfo.err->error_exit = fatal_jpeg_error; jpeg_create_decompress(&cinfo); jpeg_gdIOCtx_src(&cinfo, infile); /* 2.0.22: save the APP14 marker to check for Adobe Photoshop CMYK * files with inverted components. */ jpeg_save_markers(&cinfo, JPEG_APP0 + 14, 256); retval = jpeg_read_header(&cinfo, TRUE); if(retval != JPEG_HEADER_OK) { gd_error("gd-jpeg: warning: jpeg_read_header returns" " %d, expected %d\n", retval, JPEG_HEADER_OK); } if(cinfo.image_height > INT_MAX) { gd_error("gd-jpeg: warning: JPEG image height (%u) is" " greater than INT_MAX (%d) (and thus greater than" " gd can handle)", cinfo.image_height, INT_MAX); } if(cinfo.image_width > INT_MAX) { gd_error("gd-jpeg: warning: JPEG image width (%u) is" " greater than INT_MAX (%d) (and thus greater than" " gd can handle)\n", cinfo.image_width, INT_MAX); } im = gdImageCreateTrueColor((int)cinfo.image_width, (int)cinfo.image_height); if(im == 0) { gd_error("gd-jpeg error: cannot allocate gdImage struct\n"); goto error; } /* check if the resolution is specified */ switch (cinfo.density_unit) { case 1: im->res_x = cinfo.X_density; im->res_y = cinfo.Y_density; break; case 2: im->res_x = DPCM2DPI(cinfo.X_density); im->res_y = DPCM2DPI(cinfo.Y_density); break; } /* 2.0.22: very basic support for reading CMYK colorspace files. Nice for * thumbnails but there's no support for fussy adjustment of the * assumed properties of inks and paper. */ if((cinfo.jpeg_color_space == JCS_CMYK) || (cinfo.jpeg_color_space == JCS_YCCK)) { cinfo.out_color_space = JCS_CMYK; } else { cinfo.out_color_space = JCS_RGB; } if(jpeg_start_decompress(&cinfo) != TRUE) { gd_error("gd-jpeg: warning: jpeg_start_decompress" " reports suspended data source\n"); } #ifdef JPEG_DEBUG gd_error_ex(GD_DEBUG, "gd-jpeg: JPEG image information:"); if(cinfo.saw_JFIF_marker) { gd_error_ex(GD_DEBUG, " JFIF version %d.%.2d", (int)cinfo.JFIF_major_version, (int)cinfo.JFIF_minor_version); } else if(cinfo.saw_Adobe_marker) { gd_error_ex(GD_DEBUG, " Adobe format"); } else { gd_error_ex(GD_DEBUG, " UNKNOWN format"); } gd_error_ex(GD_DEBUG, " %ux%u (raw) / %ux%u (scaled) %d-bit", cinfo.image_width, cinfo.image_height, cinfo.output_width, cinfo.output_height, cinfo.data_precision ); gd_error_ex(GD_DEBUG, " %s", (cinfo.progressive_mode ? "progressive" : "baseline")); gd_error_ex(GD_DEBUG, " image, %d quantized colors, ", cinfo.actual_number_of_colors); switch(cinfo.jpeg_color_space) { case JCS_GRAYSCALE: gd_error_ex(GD_DEBUG, "grayscale"); break; case JCS_RGB: gd_error_ex(GD_DEBUG, "RGB"); break; case JCS_YCbCr: gd_error_ex(GD_DEBUG, "YCbCr (a.k.a. YUV)"); break; case JCS_CMYK: gd_error_ex(GD_DEBUG, "CMYK"); break; case JCS_YCCK: gd_error_ex(GD_DEBUG, "YCbCrK"); break; default: gd_error_ex(GD_DEBUG, "UNKNOWN (value: %d)", (int)cinfo.jpeg_color_space); break; } gd_error_ex(GD_DEBUG, " colorspace\n"); fflush(stdout); #endif /* JPEG_DEBUG */ /* REMOVED by TBB 2/12/01. This field of the structure is * documented as private, and sure enough it's gone in the * latest libjpeg, replaced by something else. Unfortunately * there is still no right way to find out if the file was * progressive or not; just declare your intent before you * write one by calling gdImageInterlace(im, 1) yourself. * After all, we're not really supposed to rework JPEGs and * write them out again anyway. Lossy compression, remember? */ #if 0 gdImageInterlace (im, cinfo.progressive_mode != 0); #endif if(cinfo.out_color_space == JCS_RGB) { if(cinfo.output_components != 3) { gd_error("gd-jpeg: error: JPEG color quantization" " request resulted in output_components == %d" " (expected 3 for RGB)\n", cinfo.output_components); goto error; } channels = 3; } else if(cinfo.out_color_space == JCS_CMYK) { jpeg_saved_marker_ptr marker; if(cinfo.output_components != 4) { gd_error("gd-jpeg: error: JPEG color quantization" " request resulted in output_components == %d" " (expected 4 for CMYK)\n", cinfo.output_components); goto error; } channels = 4; marker = cinfo.marker_list; while(marker) { if( (marker->marker == (JPEG_APP0 + 14)) && (marker->data_length >= 12) && (!strncmp((const char *)marker->data, "Adobe", 5))) { inverted = 1; break; } marker = marker->next; } } else { gd_error("gd-jpeg: error: unexpected colorspace\n"); goto error; } #if BITS_IN_JSAMPLE == 12 gd_error_ex(GD_ERROR, "gd-jpeg: error: jpeg library was compiled for 12-bit\n" "precision. This is mostly useless, because JPEGs on the web are\n" "8-bit and such versions of the jpeg library won't read or write\n" "them. GD doesn't support these unusual images. Edit your\n" "jmorecfg.h file to specify the correct precision and completely\n" "'make clean' and 'make install' libjpeg again. Sorry.\n"); goto error; #endif /* BITS_IN_JSAMPLE == 12 */ row = gdCalloc(cinfo.output_width *channels, sizeof(JSAMPLE)); if(row == 0) { gd_error("gd-jpeg: error: unable to allocate row for" " JPEG scanline: gdCalloc returns NULL\n"); goto error; } rowptr[0] = row; if(cinfo.out_color_space == JCS_CMYK) { for(i = 0; i < cinfo.output_height; i++) { register JSAMPROW currow = row; register int *tpix = im->tpixels[i]; nrows = jpeg_read_scanlines(&cinfo, rowptr, 1); if(nrows != 1) { gd_error("gd-jpeg: error: jpeg_read_scanlines" " returns %u, expected 1\n", nrows); goto error; } for(j = 0; j < cinfo.output_width; j++, currow += 4, tpix++) { *tpix = CMYKToRGB(currow[0], currow[1], currow[2], currow[3], inverted); } } } else { for(i = 0; i < cinfo.output_height; i++) { register JSAMPROW currow = row; register int *tpix = im->tpixels[i]; nrows = jpeg_read_scanlines(&cinfo, rowptr, 1); if(nrows != 1) { gd_error("gd-jpeg: error: jpeg_read_scanlines" " returns %u, expected 1\n", nrows); goto error; } for(j = 0; j < cinfo.output_width; j++, currow += 3, tpix++) { *tpix = gdTrueColor(currow[0], currow[1], currow[2]); } } } if(jpeg_finish_decompress (&cinfo) != TRUE) { gd_error("gd-jpeg: warning: jpeg_finish_decompress" " reports suspended data source\n"); } /* TBB 2.0.29: we should do our best to read whatever we can read, and a * warning is a warning. A fatal error on warnings doesn't make sense. */ #if 0 /* This was originally added by Truxton Fulton */ if (cinfo.err->num_warnings > 0) goto error; #endif jpeg_destroy_decompress(&cinfo); gdFree(row); return im; error: jpeg_destroy_decompress(&cinfo); if(row) { gdFree(row); } if(im) { gdImageDestroy(im); } return 0; }
int main (void) { #ifdef HAVE_LIBPNG /* Input and output files */ FILE *in; FILE *out; /* Input and output images */ gdImagePtr im_in = 0, im_out = 0; /* Brush image */ gdImagePtr brush; /* Color indexes */ int white; int blue; int red; int green; /* Points for polygon */ gdPoint points[3]; int i; /* Create output image, in true color. */ im_out = gdImageCreateTrueColor (256 + 384, 384); /* 2.0.2: first color allocated would automatically be background in a palette based image. Since this is a truecolor image, with an automatic background of black, we must fill it explicitly. */ white = gdImageColorAllocate (im_out, 255, 255, 255); gdImageFilledRectangle (im_out, 0, 0, gdImageSX (im_out), gdImageSY (im_out), white); /* Set transparent color. */ gdImageColorTransparent (im_out, white); /* Try to load demoin.png and paste part of it into the output image. */ in = fopen ("demoin.png", "rb"); if (!in) { fprintf (stderr, "Can't load source image; this demo\n"); fprintf (stderr, "is much more impressive if demoin.png\n"); fprintf (stderr, "is available.\n"); im_in = 0; } else { int a; im_in = gdImageCreateFromPng (in); fclose (in); /* Now copy, and magnify as we do so */ gdImageCopyResampled (im_out, im_in, 32, 32, 0, 0, 192, 192, 255, 255); /* Now display variously rotated space shuttles in a circle of our own */ for (a = 0; (a < 360); a += 45) { int cx = cos (a * .0174532925) * 128; int cy = -sin (a * .0174532925) * 128; gdImageCopyRotated (im_out, im_in, 256 + 192 + cx, 192 + cy, 0, 0, gdImageSX (im_in), gdImageSY (im_in), a); } } red = gdImageColorAllocate (im_out, 255, 0, 0); green = gdImageColorAllocate (im_out, 0, 255, 0); blue = gdImageColorAllocate (im_out, 0, 0, 255); /* Fat Rectangle */ gdImageSetThickness (im_out, 4); gdImageLine (im_out, 16, 16, 240, 16, green); gdImageLine (im_out, 240, 16, 240, 240, green); gdImageLine (im_out, 240, 240, 16, 240, green); gdImageLine (im_out, 16, 240, 16, 16, green); gdImageSetThickness (im_out, 1); /* Circle */ gdImageArc (im_out, 128, 128, 60, 20, 0, 720, blue); /* Arc */ gdImageArc (im_out, 128, 128, 40, 40, 90, 270, blue); /* Flood fill: doesn't do much on a continuously variable tone jpeg original. */ gdImageFill (im_out, 8, 8, blue); /* Polygon */ points[0].x = 64; points[0].y = 0; points[1].x = 0; points[1].y = 128; points[2].x = 128; points[2].y = 128; gdImageFilledPolygon (im_out, points, 3, green); /* 2.0.12: Antialiased Polygon */ gdImageSetAntiAliased (im_out, green); for (i = 0; (i < 3); i++) { points[i].x += 128; } gdImageFilledPolygon (im_out, points, 3, gdAntiAliased); /* Brush. A fairly wild example also involving a line style! */ if (im_in) { int style[8]; brush = gdImageCreateTrueColor (16, 16); gdImageCopyResized (brush, im_in, 0, 0, 0, 0, gdImageSX (brush), gdImageSY (brush), gdImageSX (im_in), gdImageSY (im_in)); gdImageSetBrush (im_out, brush); /* With a style, so they won't overprint each other. Normally, they would, yielding a fat-brush effect. */ style[0] = 0; style[1] = 0; style[2] = 0; style[3] = 0; style[4] = 0; style[5] = 0; style[6] = 0; style[7] = 1; gdImageSetStyle (im_out, style, 8); /* Draw the styled, brushed line */ gdImageLine (im_out, 0, 255, 255, 0, gdStyledBrushed); } /* Text (non-truetype; see gdtestft for a freetype demo) */ gdImageString (im_out, gdFontGiant, 32, 32, (unsigned char *) "hi", red); gdImageStringUp (im_out, gdFontSmall, 64, 64, (unsigned char *) "hi", red); /* Random antialiased lines; coordinates all over the image, but the output will respect a small clipping rectangle */ gdImageSetClip(im_out, 0, gdImageSY(im_out) - 100, 100, gdImageSY(im_out)); /* Fixed seed for reproducibility of results */ srand(100); for (i = 0; (i < 100); i++) { int x1 = rand() % gdImageSX(im_out); int y1 = rand() % gdImageSY(im_out); int x2 = rand() % gdImageSX(im_out); int y2 = rand() % gdImageSY(im_out); gdImageSetAntiAliased(im_out, white); gdImageLine (im_out, x1, y1, x2, y2, gdAntiAliased); } /* Make output image interlaced (progressive, in the case of JPEG) */ gdImageInterlace (im_out, 1); out = fopen ("demoout.png", "wb"); /* Write PNG */ gdImagePng (im_out, out); fclose (out); /* 2.0.12: also write a paletteized version */ out = fopen ("demooutp.png", "wb"); gdImageTrueColorToPalette (im_out, 0, 256); gdImagePng (im_out, out); fclose (out); gdImageDestroy (im_out); if (im_in) { gdImageDestroy (im_in); } #else fprintf (stderr, "No PNG library support.\n"); #endif /* HAVE_LIBPNG */ return 0; }
int main(void) { /* Input and output files */ FILE *in; FILE *out; /* Input and output images */ gdImagePtr im_in, im_out; /* Brush image */ gdImagePtr brush; /* Color indexes */ int white; int blue; int red; int green; /* Points for polygon */ gdPoint points[3]; /* Create output image, 128 by 128 pixels. */ im_out = gdImageCreate(128, 128); /* First color allocated is background. */ white = gdImageColorAllocate(im_out, 255, 255, 255); /* Set transparent color. */ gdImageColorTransparent(im_out, white); /* Try to load demoin.png and paste part of it into the output image. */ in = fopen("demoin.png", "rb"); if (!in) { fprintf(stderr, "Can't load source image; this demo\n"); fprintf(stderr, "is much more impressive if demoin.png\n"); fprintf(stderr, "is available.\n"); im_in = 0; } else { im_in = gdImageCreateFromPng(in); fclose(in); /* Now copy, and magnify as we do so */ gdImageCopyResized(im_out, im_in, 16, 16, 0, 0, 96, 96, 127, 127); } red = gdImageColorAllocate(im_out, 255, 0, 0); green = gdImageColorAllocate(im_out, 0, 255, 0); blue = gdImageColorAllocate(im_out, 0, 0, 255); /* Rectangle */ gdImageLine(im_out, 8, 8, 120, 8, green); gdImageLine(im_out, 120, 8, 120, 120, green); gdImageLine(im_out, 120, 120, 8, 120, green); gdImageLine(im_out, 8, 120, 8, 8, green); /* Circle */ gdImageArc(im_out, 64, 64, 30, 10, 0, 360, blue); /* Arc */ gdImageArc(im_out, 64, 64, 20, 20, 45, 135, blue); /* Flood fill */ gdImageFill(im_out, 4, 4, blue); /* Polygon */ points[0].x = 32; points[0].y = 0; points[1].x = 0; points[1].y = 64; points[2].x = 64; points[2].y = 64; gdImageFilledPolygon(im_out, points, 3, green); /* Brush. A fairly wild example also involving a line style! */ if (im_in) { int style[8]; brush = gdImageCreate(8, 8); gdImageCopyResized(brush, im_in, 0, 0, 0, 0, gdImageSX(brush), gdImageSY(brush), gdImageSX(im_in), gdImageSY(im_in)); gdImageSetBrush(im_out, brush); /* With a style, so they won't overprint each other. Normally, they would, yielding a fat-brush effect. */ style[0] = 0; style[1] = 0; style[2] = 0; style[3] = 0; style[4] = 0; style[5] = 0; style[6] = 0; style[7] = 1; gdImageSetStyle(im_out, style, 8); /* Draw the styled, brushed line */ gdImageLine(im_out, 0, 127, 127, 0, gdStyledBrushed); } /* Text */ gdImageString(im_out, gdFontGiant, 16, 16, (unsigned char *) "hi", red); gdImageStringUp(im_out, gdFontSmall, 32, 32, (unsigned char *) "hi", red); /* Make output image interlaced (allows "fade in" in some viewers, and in the latest web browsers) */ gdImageInterlace(im_out, 1); out = fopen("demoout.png", "wb"); /* Write PNG */ gdImagePng(im_out, out); fclose(out); gdImageDestroy(im_out); if (im_in) { gdImageDestroy(im_in); } return 0; }
gdImagePtr gdImageCreateFromJpegCtxEx (gdIOCtx * infile, int ignore_warning) { struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; jmpbuf_wrapper jmpbufw; /* volatile so we can gdFree them after longjmp */ volatile JSAMPROW row = 0; volatile gdImagePtr im = 0; JSAMPROW rowptr[1]; unsigned int i, j; int retval; JDIMENSION nrows; int channels = 3; int inverted = 0; memset (&cinfo, 0, sizeof (cinfo)); memset (&jerr, 0, sizeof (jerr)); jmpbufw.ignore_warning = ignore_warning; cinfo.err = jpeg_std_error (&jerr); cinfo.client_data = &jmpbufw; cinfo.err->emit_message = (void (*)(j_common_ptr,int)) php_jpeg_emit_message; if (setjmp (jmpbufw.jmpbuf) != 0) { /* we're here courtesy of longjmp */ if (row) { gdFree (row); } if (im) { gdImageDestroy (im); } return 0; } cinfo.err->error_exit = fatal_jpeg_error; jpeg_create_decompress (&cinfo); jpeg_gdIOCtx_src (&cinfo, infile); /* 2.0.22: save the APP14 marker to check for Adobe Photoshop CMYK files with inverted components. */ jpeg_save_markers(&cinfo, JPEG_APP0 + 14, 256); retval = jpeg_read_header (&cinfo, TRUE); if (retval != JPEG_HEADER_OK) { php_gd_error_ex(E_WARNING, "gd-jpeg: warning: jpeg_read_header returned %d, expected %d", retval, JPEG_HEADER_OK); } if (cinfo.image_height > INT_MAX) { php_gd_error_ex(E_WARNING, "gd-jpeg: warning: JPEG image height (%u) is greater than INT_MAX (%d) (and thus greater than gd can handle)", cinfo.image_height, INT_MAX); } if (cinfo.image_width > INT_MAX) { php_gd_error_ex(E_WARNING, "gd-jpeg: warning: JPEG image width (%u) is greater than INT_MAX (%d) (and thus greater than gd can handle)", cinfo.image_width, INT_MAX); } im = gdImageCreateTrueColor ((int) cinfo.image_width, (int) cinfo.image_height); if (im == 0) { php_gd_error("gd-jpeg error: cannot allocate gdImage struct"); goto error; } /* 2.0.22: very basic support for reading CMYK colorspace files. Nice for * thumbnails but there's no support for fussy adjustment of the * assumed properties of inks and paper. */ if ((cinfo.jpeg_color_space == JCS_CMYK) || (cinfo.jpeg_color_space == JCS_YCCK)) { cinfo.out_color_space = JCS_CMYK; } else { cinfo.out_color_space = JCS_RGB; } if (jpeg_start_decompress (&cinfo) != TRUE) { php_gd_error("gd-jpeg: warning: jpeg_start_decompress reports suspended data source"); } /* REMOVED by TBB 2/12/01. This field of the structure is * documented as private, and sure enough it's gone in the * latest libjpeg, replaced by something else. Unfortunately * there is still no right way to find out if the file was * progressive or not; just declare your intent before you * write one by calling gdImageInterlace(im, 1) yourself. * After all, we're not really supposed to rework JPEGs and * write them out again anyway. Lossy compression, remember? */ #if 0 gdImageInterlace (im, cinfo.progressive_mode != 0); #endif if (cinfo.out_color_space == JCS_RGB) { if (cinfo.output_components != 3) { php_gd_error_ex(E_WARNING, "gd-jpeg: error: JPEG color quantization request resulted in output_components == %d (expected 3 for RGB)", cinfo.output_components); goto error; } channels = 3; } else if (cinfo.out_color_space == JCS_CMYK) { jpeg_saved_marker_ptr marker; if (cinfo.output_components != 4) { php_gd_error_ex(E_WARNING, "gd-jpeg: error: JPEG color quantization request resulted in output_components == %d (expected 4 for CMYK)", cinfo.output_components); goto error; } channels = 4; marker = cinfo.marker_list; while (marker) { if ((marker->marker == (JPEG_APP0 + 14)) && (marker->data_length >= 12) && (!strncmp((const char *) marker->data, "Adobe", 5))) { inverted = 1; break; } marker = marker->next; } } else { php_gd_error_ex(E_WARNING, "gd-jpeg: error: unexpected colorspace."); goto error; } #if BITS_IN_JSAMPLE == 12 php_gd_error("gd-jpeg: error: jpeg library was compiled for 12-bit precision. This is mostly useless, because JPEGs on the web are 8-bit and such versions of the jpeg library won't read or write them. GD doesn't support these unusual images. Edit your jmorecfg.h file to specify the correct precision and completely 'make clean' and 'make install' libjpeg again. Sorry."); goto error; #endif /* BITS_IN_JSAMPLE == 12 */ row = safe_emalloc(cinfo.output_width * channels, sizeof(JSAMPLE), 0); memset(row, 0, cinfo.output_width * channels * sizeof(JSAMPLE)); rowptr[0] = row; if (cinfo.out_color_space == JCS_CMYK) { for (i = 0; i < cinfo.output_height; i++) { register JSAMPROW currow = row; register int *tpix = im->tpixels[i]; nrows = jpeg_read_scanlines (&cinfo, rowptr, 1); if (nrows != 1) { php_gd_error_ex(E_WARNING, "gd-jpeg: error: jpeg_read_scanlines returns %u, expected 1", nrows); goto error; } for (j = 0; j < cinfo.output_width; j++, currow += 4, tpix++) { *tpix = CMYKToRGB (currow[0], currow[1], currow[2], currow[3], inverted); } } } else { for (i = 0; i < cinfo.output_height; i++) { register JSAMPROW currow = row; register int *tpix = im->tpixels[i]; nrows = jpeg_read_scanlines (&cinfo, rowptr, 1); if (nrows != 1) { php_gd_error_ex(E_WARNING, "gd-jpeg: error: jpeg_read_scanlines returns %u, expected 1", nrows); goto error; } for (j = 0; j < cinfo.output_width; j++, currow += 3, tpix++) { *tpix = gdTrueColor (currow[0], currow[1], currow[2]); } } } if (jpeg_finish_decompress (&cinfo) != TRUE) { php_gd_error("gd-jpeg: warning: jpeg_finish_decompress reports suspended data source"); } if (!ignore_warning) { if (cinfo.err->num_warnings > 0) { goto error; } } jpeg_destroy_decompress (&cinfo); gdFree (row); return im; error: jpeg_destroy_decompress (&cinfo); if (row) { gdFree (row); } if (im) { gdImageDestroy (im); } return 0; }
static ngx_buf_t * ngx_http_image_resize(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx) { int sx, sy, dx, dy, ox, oy, ax, ay, size, colors, palette, transparent, sharpen, red, green, blue, t; u_char *out; ngx_buf_t *b; ngx_uint_t resize; gdImagePtr src, dst; ngx_pool_cleanup_t *cln; ngx_http_image_filter_conf_t *conf; src = ngx_http_image_source(r, ctx); if (src == NULL) { return NULL; } sx = gdImageSX(src); sy = gdImageSY(src); conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module); if (!ctx->force && ctx->angle == 0 && (ngx_uint_t) sx <= ctx->max_width && (ngx_uint_t) sy <= ctx->max_height) { gdImageDestroy(src); return ngx_http_image_asis(r, ctx); } colors = gdImageColorsTotal(src); if (colors && conf->transparency) { transparent = gdImageGetTransparent(src); if (transparent != -1) { palette = colors; red = gdImageRed(src, transparent); green = gdImageGreen(src, transparent); blue = gdImageBlue(src, transparent); goto transparent; } } palette = 0; transparent = -1; red = 0; green = 0; blue = 0; transparent: gdImageColorTransparent(src, -1); dx = sx; dy = sy; if (conf->filter == NGX_HTTP_IMAGE_RESIZE) { if ((ngx_uint_t) dx > ctx->max_width) { dy = dy * ctx->max_width / dx; dy = dy ? dy : 1; dx = ctx->max_width; } if ((ngx_uint_t) dy > ctx->max_height) { dx = dx * ctx->max_height / dy; dx = dx ? dx : 1; dy = ctx->max_height; } resize = 1; } else if (conf->filter == NGX_HTTP_IMAGE_ROTATE) { resize = 0; } else if (conf->filter == NGX_HTTP_IMAGE_WATERMARK) { resize = 0; } else { /* NGX_HTTP_IMAGE_CROP */ resize = 0; if ((double) dx / dy < (double) ctx->max_width / ctx->max_height) { if ((ngx_uint_t) dx > ctx->max_width) { dy = dy * ctx->max_width / dx; dy = dy ? dy : 1; dx = ctx->max_width; resize = 1; } } else { if ((ngx_uint_t) dy > ctx->max_height) { dx = dx * ctx->max_height / dy; dx = dx ? dx : 1; dy = ctx->max_height; resize = 1; } } } if (resize) { dst = ngx_http_image_new(r, dx, dy, palette); if (dst == NULL) { gdImageDestroy(src); return NULL; } if (colors == 0) { gdImageSaveAlpha(dst, 1); gdImageAlphaBlending(dst, 0); } gdImageCopyResampled(dst, src, 0, 0, 0, 0, dx, dy, sx, sy); if (colors) { gdImageTrueColorToPalette(dst, 1, 256); } gdImageDestroy(src); } else { dst = src; } if (ctx->angle) { src = dst; ax = (dx % 2 == 0) ? 1 : 0; ay = (dy % 2 == 0) ? 1 : 0; switch (ctx->angle) { case 90: case 270: dst = ngx_http_image_new(r, dy, dx, palette); if (dst == NULL) { gdImageDestroy(src); return NULL; } if (ctx->angle == 90) { ox = dy / 2 + ay; oy = dx / 2 - ax; } else { ox = dy / 2 - ay; oy = dx / 2 + ax; } gdImageCopyRotated(dst, src, ox, oy, 0, 0, dx + ax, dy + ay, ctx->angle); gdImageDestroy(src); t = dx; dx = dy; dy = t; break; case 180: dst = ngx_http_image_new(r, dx, dy, palette); if (dst == NULL) { gdImageDestroy(src); return NULL; } gdImageCopyRotated(dst, src, dx / 2 - ax, dy / 2 - ay, 0, 0, dx + ax, dy + ay, ctx->angle); gdImageDestroy(src); break; } } if (conf->filter == NGX_HTTP_IMAGE_CROP) { src = dst; if ((ngx_uint_t) dx > ctx->max_width) { ox = dx - ctx->max_width; } else { ox = 0; } if ((ngx_uint_t) dy > ctx->max_height) { oy = dy - ctx->max_height; } else { oy = 0; } if (ox || oy) { dst = ngx_http_image_new(r, dx - ox, dy - oy, colors); if (dst == NULL) { gdImageDestroy(src); return NULL; } ox /= 2; oy /= 2; ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "image crop: %d x %d @ %d x %d", dx, dy, ox, oy); if (colors == 0) { gdImageSaveAlpha(dst, 1); gdImageAlphaBlending(dst, 0); } gdImageCopy(dst, src, 0, 0, ox, oy, dx - ox, dy - oy); if (colors) { gdImageTrueColorToPalette(dst, 1, 256); } gdImageDestroy(src); } } if (transparent != -1 && colors) { gdImageColorTransparent(dst, gdImageColorExact(dst, red, green, blue)); } if (conf->filter == NGX_HTTP_IMAGE_WATERMARK && conf->watermark.data) { FILE *watermark_file = fopen((const char *)conf->watermark.data, "r"); if (watermark_file) { gdImagePtr watermark, watermark_mix; ngx_int_t wdx = 0, wdy = 0; watermark = gdImageCreateFromPng(watermark_file); if(watermark != NULL) { watermark_mix = gdImageCreateTrueColor(watermark->sx, watermark->sy); if (ngx_strcmp(conf->watermark_position.data, "bottom-right") == 0) { wdx = dx - watermark->sx - 10; wdy = dy - watermark->sy - 10; } else if (ngx_strcmp(conf->watermark_position.data, "top-left") == 0) { wdx = wdy = 10; } else if (ngx_strcmp(conf->watermark_position.data, "top-right") == 0) { wdx = dx - watermark->sx - 10; wdy = 10; } else if (ngx_strcmp(conf->watermark_position.data, "bottom-left") == 0) { wdx = 10; wdy = dy - watermark->sy - 10; } else if (ngx_strcmp(conf->watermark_position.data, "center") == 0) { wdx = dx / 2 - watermark->sx / 2; wdy = dy / 2 - watermark->sy / 2; } gdImageCopy(watermark_mix, dst, 0, 0, wdx, wdy, watermark->sx, watermark->sy); gdImageCopy(watermark_mix, watermark, 0, 0, 0, 0, watermark->sx, watermark->sy); gdImageCopyMerge(dst, watermark_mix, wdx, wdy, 0, 0, watermark->sx, watermark->sy, 75); gdFree(watermark); gdFree(watermark_mix); } else { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "watermark file '%s' is not PNG", conf->watermark.data);} } else { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "watermark file '%s' not found", conf->watermark.data); } } sharpen = ngx_http_image_filter_get_value(r, conf->shcv, conf->sharpen); if (sharpen > 0) { gdImageSharpen(dst, sharpen); } gdImageInterlace(dst, (int) conf->interlace); out = ngx_http_image_out(r, ctx->type, dst, &size); ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "image: %d x %d %d", sx, sy, colors); gdImageDestroy(dst); ngx_pfree(r->pool, ctx->image); if (out == NULL) { return NULL; } cln = ngx_pool_cleanup_add(r->pool, 0); if (cln == NULL) { gdFree(out); return NULL; } b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); if (b == NULL) { gdFree(out); return NULL; } cln->handler = ngx_http_image_cleanup; cln->data = out; b->pos = out; b->last = out + size; b->memory = 1; b->last_buf = 1; ngx_http_image_length(r, b); return b; }
int main(int argc, char **argv) { FILE *in; FILE *out; /* Declare our image pointer */ gdImagePtr im = 0; int i; /* We'll clear 'no' once we know the user has made a reasonable request. */ int no = 1; /* We'll set 'write' once we know the user's request requires that the image be written back to disk. */ int write = 0; /* C programs always get at least one argument; we want at least one more (the image), more in practice. */ if (argc < 2) { no = 1; goto usage; } /* The last argument should be the image. Open the file. */ in = fopen(argv[argc-1], "rb"); if (!in) { fprintf(stderr, "Error: can't open file %s.\n", argv[argc-1]); } /* Now load the image. */ im = gdImageCreateFromGif(in); fclose(in); /* If the load failed, it must not be a GIF file. */ if (!im) { fprintf(stderr, "Error: %s is not a valid gif file.\n", argv[1]); exit(1); } /* Consider each argument in turn. */ for (i=1; (i < (argc-1)); i++) { /* -i turns on and off interlacing. */ if (!strcmp(argv[i], "-i")) { if (i == (argc-2)) { fprintf(stderr, "Error: -i specified without y or n.\n"); no = 1; goto usage; } if (!strcmp(argv[i+1], "y")) { /* Set interlace. */ gdImageInterlace(im, 1); } else if (!strcmp(argv[i+1], "n")) { /* Clear interlace. */ gdImageInterlace(im, 0); } else { fprintf(stderr, "Error: -i specified without y or n.\n"); no = 1; goto usage; } i++; no = 0; write = 1; } else if (!strcmp(argv[i], "-t")) { /* Set transparent index (or none). */ int index; if (i == (argc-2)) { fprintf(stderr, "Error: -t specified without a color table index.\n"); no = 1; goto usage; } if (!strcmp(argv[i+1], "none")) { /* -1 means not transparent. */ gdImageColorTransparent(im, -1); } else { /* OK, get an integer and set the index. */ index = atoi(argv[i+1]); gdImageColorTransparent(im, index); } i++; write = 1; no = 0; } else if (!strcmp(argv[i], "-l")) { /* List the colors in the color table. */ int j; /* Tabs used below. */ printf("Index Red Green Blue\n"); for (j=0; (j < gdImageColorsTotal(im)); j++) { /* Use access macros to learn colors. */ printf("%d %d %d %d\n", j, gdImageRed(im, j), gdImageGreen(im, j), gdImageBlue(im, j)); } no = 0; } else if (!strcmp(argv[i], "-d")) { /* Output dimensions, etc. */ int t; printf("Width: %d Height: %d Colors: %d\n", gdImageSX(im), gdImageSY(im), gdImageColorsTotal(im)); t = gdImageGetTransparent(im); if (t != (-1)) { printf("Transparent index: %d\n", t); } else { /* -1 means the image is not transparent. */ printf("Transparent index: none\n"); } if (gdImageGetInterlaced(im)) { printf("Interlaced: yes\n"); } else { printf("Interlaced: no\n"); } no = 0; } else { fprintf(stderr, "Unknown argument: %s\n", argv[i]); break; } } usage: if (no) { /* If the command failed, output an explanation. */ fprintf(stderr, "Usage: webgif [-i y|n ] [-l] [-t index|off ] [-d] gifname.gif\n"); fprintf(stderr, "Where -i controls interlace (specify y or n for yes or no),\n"); fprintf(stderr, "-l outputs a table of color indexes, -t sets the specified\n"); fprintf(stderr, "color index (0-255 or none) to be the transparent color, and\n"); fprintf(stderr, "-d reports the dimensions and other characteristics of the image.\n"); fprintf(stderr, "Note: you may wish to pipe to \"more\" when using the -l option.\n"); } if (write) { /* Open a temporary file. */ out = fopen("temp.tmp", "wb"); if (!out) { fprintf(stderr, "Unable to write to temp.tmp -- exiting\n"); exit(1); } /* Write the new gif. */ gdImageGif(im, out); fclose(out); /* Erase the old gif. */ unlink(argv[argc-1]); /* Rename the new to the old. */ rename("temp.tmp", argv[argc-1]); } /* Delete the image from memory. */ if (im) { gdImageDestroy(im); } /* All's well that ends well. */ return 0; }
void main(int argc, char * argv[]){ FILE *infile,*outfile,*geofile; char *line,*token,*in_fname,*fs_fname,*out_fname,*base_fname,*label; int nxny,i=0,j=0; int finput = 0,pngflag=0,foutput = 0,flabel=0,cflg,errflg,ctrlflg = 0; int xsize=0,ysize=0,nc[3]; CA_FLOAT part_coef=0.1; extern int optind; extern char *optarg; CA_FLOAT *data,*datastart,*fsdata,*cdata,maxdat=0; float pngmax,pngvalue; int pngcolours[32]; int index=0; int maxflag=0; gdImagePtr im_out; out_fname = (char *)calloc(MAX_WORD_LENGTH,sizeof(char)); in_fname = (char *)calloc(MAX_WORD_LENGTH,sizeof(char)); fs_fname = (char *)calloc(MAX_WORD_LENGTH,sizeof(char)); base_fname = (char *)calloc(MAX_WORD_LENGTH,sizeof(char)); label = (char *)calloc(MAX_WORD_LENGTH,sizeof(char)); line = (char *) calloc(MAX_STRING_LEN ,sizeof(char)); token = (char *) calloc(MAX_STRING_LEN ,sizeof(char)); errflg=0; fprintf(stderr,"$Id: fsres.c 895 2006-03-10 16:12:45Z rcatwood $\n"); if (argc == 1) errflg=TRUE; fprintf(stderr,"\n"); while ((cflg = getopt(argc, argv, "ai:o:d:hl:gp:k:")) != -1) { switch (cflg) { case 'a': fprintf(stderr,"%s: sorry, flag 'a' is not defined\n",argv[0]); break; case 'p': fprintf(stderr,"Output png file\n"); pngflag = 1; pngmax = atof(optarg); if (pngmax == 0){ pngmax = 1; maxflag = 1; } break; case 'k': part_coef = atof(optarg); break; case 'g': fprintf(stderr,"Using control file ca_geoplus.in\n"); ctrlflg = 1; break; case 'i': /* get input filename */ finput = TRUE; in_fname=strdup(optarg); debin (base_fname,in_fname); /*base_fname=strdup(optarg);*/ /*sprintf(in_fname,"%s.bin",base_fname);*/ break; case 'd': if (!(xsize = atoi(optarg))){ fprintf(stderr,"ERROR with d argument: %s\n",optarg); errflg = TRUE; } if (!( ysize = atoi(argv[optind]))){ fprintf(stderr,"ERROR with d argument: %s\n",argv[optind]); errflg = TRUE; } optind++; break; case 'o': /* get output filename */ foutput = TRUE; out_fname = strdup(optarg); break; case 'l': /* get label string */ flabel = TRUE; label = strdup(optarg); break; case 'h': errflg=TRUE; break; default: errflg=TRUE; break; } } if (errflg ) { fprintf(stderr,"%s -i infile [-o outfile] "\ "-d xsize ysize,or \n"\ "-g to read ca_geoplus for size\n"\ "-p maxval to create PNG file \n"\ "-k partition-coefficient to calculate true conc. \n"\ "-l label to label the tecplot results(default is CA_RESULTS) \n"\ "Default out is [infile].dat\n",argv[0]); exit(0); } if (!foutput){ sprintf(out_fname,"%s.dat",base_fname); fprintf(stderr,"Default output filename used: %s\n",out_fname); } if (!finput){ fprintf(stderr,"ERROR: no input file specified! \n"); exit(0); } fprintf(stderr,"Creating 2-d data file for TecPlot\n"); fprintf(stderr,"Processing CA_FLOAT results from %s into %s\n",in_fname,out_fname); if (!(outfile = fopen(out_fname,"w"))){ fprintf(stderr,"ERROR: could not open outfile %s\n",out_fname); exit(0); } if (ctrlflg){ if ( (geofile = fopen("ca_geoplus.in","r"))== NULL ){ fprintf(stderr,"ERROR, could not open ca_geoplus.in\n"); exit(0); }else{ while (fgets(line,MAX_STRING_LEN,geofile)!= NULL){ if(line[0]=='%' || line[0]=='#'||(token = strtok(line," ,;\t"))==NULL) { continue; }else if (strcasecmp(token,"NCellsPerSB") == 0){ for (i=0; i<3; i++) { if ((token = strtok(NULL, " ,;\t")) != NULL) nc[i] = atoi(token); else { fprintf(stderr,"Error: NCellsPerSB,not found\n"); exit(0); } } } }/*end of while loop for getting lines*/ fclose(geofile); xsize = nc[0]; ysize = nc[1]; } }/* end of read geo file */ printf("xsize = %i, ysize = %i\n",xsize,ysize); nxny = xsize * ysize; if (nxny <= 0) { fprintf(stderr,"ERROR: size is wrong: %i\n",nxny); fprintf(stderr,"\nSpecifiy -d xsize ysize\n"); fprintf(stderr,"or -g to read file ca_geoplus.in \n\n"); exit(0); } if (pngflag){ im_out=gdImageCreate(xsize,ysize); #ifdef RANDCOLOUR for(i=0;i<32;i++){ pngcolours[i]=gdImageColorAllocate(im_out,colours[3*i],colours[3*i+1],colours[3*i+2]); } #else pngcolours[0]=gdImageColorAllocate(im_out,255,255,255); pngcolours[31]=gdImageColorAllocate(im_out,255,85,85); for(i=1;i<31;i++){ pngcolours[i]=gdImageColorAllocate(im_out,255 - 8*i,255-8*i,255-8*i); } #endif } #ifdef ALL_VAR if (flabel) fprintf(outfile,"VARIABLES =\"x\",\"y\", \"%s\"\n",label); else fprintf (outfile,"VARIABLES = \"x\",\"y\", \"CA RESULTS\"\n"); #else if (flabel) fprintf(outfile,"VARIABLES = \"%s\"\n",label); else fprintf (outfile,"VARIABLES = \"CA RESULTS\"\n"); #endif/*ALL_VAR*/ #ifdef ALL_VAR fprintf (outfile,"ZONE I=%i,J=%i,F=POINT\n",xsize,ysize); #else fprintf (outfile,"ZONE I=%i,J=%i\n",xsize,ysize); #endif/*ALL_VAR*/ data = datastart = (CA_FLOAT *) malloc ( nxny * sizeof(CA_FLOAT)); fsdata = (CA_FLOAT *) malloc ( nxny * sizeof(CA_FLOAT)); cdata = (CA_FLOAT *) malloc ( nxny * sizeof(CA_FLOAT)); if (!(infile = fopen(in_fname,"r"))){ fprintf(stderr,"ERROR: could not open infile %s\n",in_fname); exit(0); } fread(cdata,sizeof(CA_FLOAT),nxny,infile); fclose(infile); sprintf(fs_fname,"F_FS_%s",in_fname+4); if (!(infile = fopen(fs_fname,"r"))){ fprintf(stderr,"ERROR: could not open infile %s\n",fs_fname); exit(0); } fread(fsdata,sizeof(CA_FLOAT),nxny,infile); fclose(infile); for (j=0;j<ysize;j++){ for(i=0;i<xsize;i++){ *data = ((1-(1-part_coef) * *fsdata) * *cdata); if(pngflag){ if (maxflag){ maxdat = (maxdat > *data)? maxdat:*data; }else{ pngvalue = 30* (float)(*data) / pngmax; if (pngvalue > 30) pngvalue = 30; if (pngvalue < 0) pngvalue = 31; index = (int)(floorf(pngvalue)); gdImageSetPixel(im_out,i,j,pngcolours[index]); } } #ifdef ALL_VAR fprintf(outfile,"%i %i %.10g\n",i,j,*data); #else fprintf(outfile,"%.10g\n",*data); #endif/*ALL_VAR*/ data++; fsdata++; cdata++; } } if(maxflag && pngflag){ data = datastart; /*rewind*/ pngmax = maxdat; for (j=0;j<ysize;j++){ for(i=0;i<xsize;i++){ pngvalue = 31* (float)(*data) / pngmax; if (pngvalue > 31) pngvalue = 31; if (pngvalue < 0) pngvalue = 0; index = (int)(floorf(pngvalue)); gdImageSetPixel(im_out,i,j,pngcolours[index]); data++; } } } fclose(outfile); if(pngflag){ /*********write out the PNG output************/ gdImageInterlace(im_out,1); sprintf(out_fname,"%s.png",base_fname); outfile=fopen(out_fname,"w"); gdImagePng(im_out,outfile); fclose(outfile); fprintf(stderr,"Created file %s\n",out_fname); } fprintf(stderr,"Total lines processed %i\n",i); }
ngx_int_t ngx_http_small_light_gd_process(ngx_http_request_t *r, ngx_http_small_light_ctx_t *ctx) { ngx_http_small_light_gd_ctx_t *ictx; ngx_http_small_light_image_size_t sz; gdImagePtr src, dst, canvas; ngx_int_t colors, transparent, palette, red, green, blue; ngx_int_t ax, ay, ox, oy, type; int iw, ih, radius, ccolor, bcolor; char *sharpen, *of; u_char *out; int size; double q; ictx = (ngx_http_small_light_gd_ctx_t *)ctx->ictx; src = ngx_http_small_light_gd_src(ictx); if (src == NULL) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "failed to get image source %s:%d", __FUNCTION__, __LINE__); return NGX_ERROR; } /* adjust image size */ iw = gdImageSX(src); ih = gdImageSY(src); ngx_http_small_light_calc_image_size(r, ctx, &sz, iw, ih); colors = gdImageColorsTotal(src); palette = 0; transparent = -1; red = 0; green = 0; blue = 0; if (colors) { transparent = gdImageGetTransparent(src); if (transparent != -1) { palette = colors; red = gdImageRed(src, transparent); green = gdImageGreen(src, transparent); blue = gdImageBlue(src, transparent); } } gdImageColorTransparent(src, -1); /* rotate. */ if (sz.angle) { dst = src; ax = (iw % 2 == 0) ? 1 : 0; ay = (ih % 2 == 0) ? 1 : 0; switch (sz.angle) { case 90: case 270: dst = ngx_http_small_light_gd_new(ih, iw, palette); if (dst == NULL) { gdImageDestroy(src); return NGX_ERROR; } if (sz.angle == 90) { ox = ih / 2 - ay; oy = iw / 2 + ax; } else { ox = ih / 2 + ay; oy = iw / 2 - ax; } gdImageCopyRotated(dst, src, ox, oy, 0, 0, iw, ih, -sz.angle); gdImageDestroy(src); break; case 180: dst = ngx_http_small_light_gd_new(iw, ih, palette); if (dst == NULL) { gdImageDestroy(src); return NGX_ERROR; } gdImageCopyRotated(dst, src, iw / 2 - ax, ih / 2 - ay, 0, 0, iw + ax, ih + ay, sz.angle); gdImageDestroy(src); break; default: ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "image not rotated. 'angle'(%ui) must be 90 or 180 or 270. %s:%d", sz.angle, __FUNCTION__, __LINE__); break; } src = dst; } /* calc size. */ iw = gdImageSX(src); ih = gdImageSY(src); ngx_http_small_light_calc_image_size(r, ctx, &sz, iw, ih); /* pass through. */ if (sz.pt_flg != 0) { gdImageDestroy(src); ctx->of = ctx->inf; return NGX_OK; } /* crop, scale. */ if (sz.scale_flg != 0) { dst = ngx_http_small_light_gd_new(sz.dw, sz.dh, palette); if (dst == NULL) { gdImageDestroy(src); return NGX_ERROR; } if (colors == 0) { gdImageSaveAlpha(dst, 1); gdImageAlphaBlending(dst, 0); } gdImageCopyResampled(dst, src, 0, 0, sz.sx, sz.sy, sz.dw, sz.dh, sz.sw, sz.sh); if (colors) { gdImageTrueColorToPalette(dst, 1, 256); } gdImageDestroy(src); } else { dst = src; } if (transparent != -1 && colors) { gdImageColorTransparent(dst, gdImageColorExact(dst, red, green, blue)); } /* effects. */ sharpen = NGX_HTTP_SMALL_LIGHT_PARAM_GET_LIT(&ctx->hash, "sharpen"); if (sharpen != NULL) { radius = ngx_http_small_light_parse_int(sharpen); if (radius > 0) { gdImageSharpen(dst, radius); } } /* interlace */ gdImageInterlace(dst, 1); /* create canvas then draw image to the canvas. */ if (sz.cw > 0.0 && sz.ch > 0.0) { canvas = gdImageCreateTrueColor(sz.cw, sz.ch); if (canvas == NULL) { gdImageDestroy(dst); return NGX_ERROR; } ccolor = gdImageColorAllocateAlpha(canvas, sz.cc.r, sz.cc.g, sz.cc.b, sz.cc.a); gdImageFilledRectangle(canvas, 0, 0, sz.cw, sz.ch, ccolor); gdImageCopy(canvas, dst, sz.dx, sz.dy, 0, 0, sz.dw, sz.dh); gdImageDestroy(dst); dst = canvas; } /* border. */ if (sz.bw > 0.0 || sz.bh > 0.0) { bcolor = gdImageColorAllocateAlpha(dst, sz.bc.r, sz.bc.g, sz.bc.b, sz.bc.a); if (sz.cw > 0.0 && sz.ch > 0.0) { gdImageFilledRectangle(dst, 0, 0, sz.cw, sz.bh, bcolor); gdImageFilledRectangle(dst, 0, 0, sz.bw, sz.ch, bcolor); gdImageFilledRectangle(dst, 0, sz.ch - sz.bh, sz.cw - 1, sz.ch - 1, bcolor); gdImageFilledRectangle(dst, sz.cw - sz.bw, 0, sz.cw - 1, sz.ch - 1, bcolor); } else { gdImageFilledRectangle(dst, 0, 0, sz.dw, sz.bh, bcolor); gdImageFilledRectangle(dst, 0, 0, sz.bw, sz.dh, bcolor); gdImageFilledRectangle(dst, 0, sz.dh - sz.bh, sz.dw - 1, sz.dh - 1, bcolor); gdImageFilledRectangle(dst, sz.dw - sz.bw, 0, sz.dw - 1, sz.dh - 1, bcolor); } } of = NGX_HTTP_SMALL_LIGHT_PARAM_GET_LIT(&ctx->hash, "of"); if (ngx_strlen(of) > 0) { type = ngx_http_small_light_type(of); if (type == NGX_HTTP_SMALL_LIGHT_IMAGE_NONE) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "of is invalid(%s) %s:%d", of, __FUNCTION__, __LINE__); } else if (type == NGX_HTTP_SMALL_LIGHT_IMAGE_WEBP) { #ifdef NGX_HTTP_SMALL_LIGHT_GD_WEBP_ENABLED ictx->type = type; #else ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "WebP is not supported %s:%d", __FUNCTION__, __LINE__); #endif } else { ictx->type = type; } } ctx->of = ngx_http_small_light_image_types[ictx->type - 1]; q = ngx_http_small_light_parse_double(NGX_HTTP_SMALL_LIGHT_PARAM_GET_LIT(&ctx->hash, "q")); if (q == 0) { q = 100; } out = ngx_http_small_light_gd_out(dst, ictx->type, (int *)&size, q); gdImageDestroy(dst); if (out == NULL) { return NGX_ERROR; } /* get small_lighted image as binary. */ ctx->content = out; ctx->content_length = size; ngx_pfree(r->pool, ctx->content_orig); ictx->complete = 1; return NGX_OK; }
int main(int argc, char **argv) { FILE *in; FILE *out; char outFn[20]; int useStdinStdout=0; /* Declare our image pointer */ gdImagePtr im = 0; int i; /* We'll clear 'no' once we know the user has made a reasonable request. */ int no = 1; /* We'll set 'write' once we know the user's request requires that the image be written back to disk. */ int write = 0; /* C programs always get at least one argument; we want at least one more (the image), more in practice. */ if (argc < 2 || !strcmp(argv[1], "--help")) { no = 1; goto usage; } /* The last argument should be the image. Open the file. */ if (strcmp("-", argv[argc-1])==0) { /* - is synonymous with STDIN */ useStdinStdout = 1; in = stdin; } else { in = fopen(argv[argc-1], "rb"); } if (!in) { fprintf(stderr, "Error: can't open file %s.\n", argv[argc-1]); exit(1); } /* Now load the image. */ im = gdImageCreateFromPng(in); fclose(in); /* If the load failed, it must not be a PNG file. */ if (!im) { fprintf(stderr, "Error: %s is not a valid PNG file.\n", argv[argc-1]); exit(1); } /* Consider each argument in turn. */ for (i=1; (i < (argc-1)); i++) { /* -i turns on and off interlacing. */ if (!strcmp(argv[i], "--help")) { /* Every program should use this for help! :) */ no = 1; goto usage; } else if (!strcmp(argv[i], "-i")) { if (i == (argc-2)) { fprintf(stderr, "Error: -i specified without y or n.\n"); no = 1; goto usage; } if (!strcmp(argv[i+1], "y")) { /* Set interlace. */ gdImageInterlace(im, 1); } else if (!strcmp(argv[i+1], "n")) { /* Clear interlace. */ gdImageInterlace(im, 0); } else { fprintf(stderr, "Error: -i specified without y or n.\n"); no = 1; goto usage; } i++; no = 0; write = 1; } else if (!strcmp(argv[i], "-t")) { /* Set transparent index (or none). */ int index; if (i == (argc-2)) { fprintf(stderr, "Error: -t specified without a color table index.\n"); no = 1; goto usage; } if (!strcmp(argv[i+1], "none")) { /* -1 means not transparent. */ gdImageColorTransparent(im, -1); } else { /* OK, get an integer and set the index. */ index = atoi(argv[i+1]); gdImageColorTransparent(im, index); } i++; write = 1; no = 0; } else if (!strcmp(argv[i], "-l")) { /* List the colors in the color table. */ int j; /* Tabs used below. */ printf("Index Red Green Blue\n"); for (j=0; (j < gdImageColorsTotal(im)); j++) { /* Use access macros to learn colors. */ printf("%d %d %d %d\n", j, gdImageRed(im, j), gdImageGreen(im, j), gdImageBlue(im, j)); } no = 0; } else if (!strcmp(argv[i], "-d")) { /* Output dimensions, etc. */ int t; printf("Width: %d Height: %d Colors: %d\n", gdImageSX(im), gdImageSY(im), gdImageColorsTotal(im)); t = gdImageGetTransparent(im); if (t != (-1)) { printf("Transparent index: %d\n", t); } else { /* -1 means the image is not transparent. */ printf("Transparent index: none\n"); } if (gdImageGetInterlaced(im)) { printf("Interlaced: yes\n"); } else { printf("Interlaced: no\n"); } no = 0; } else { fprintf(stderr, "Unknown argument: %s\n", argv[i]); break; } } usage: if (no) { /* If the command failed, output an explanation. */ fprintf(stderr, "Usage: webpng [-i y|n ] [-l] [-t index|none ] [-d] pngname.png\n" " -i [y|n] Turns on/off interlace\n" " -l Prints the table of color indexes\n" " -t [index] Set the transparent color to the specified index (0-255 or \"none\")\n" " -d Reports the dimensions and other characteristics of the image.\n" "\n" "If you specify '-' as the input file, stdin/stdout will be used input/output.\n" ); } if (write) { if (useStdinStdout) { out = stdout; } else { /* Open a temporary file. */ /* "temp.tmp" is not good temporary filename. */ sprintf(outFn, "webpng.tmp%d", getpid()); out = fopen(outFn, "wb"); if (!out) { fprintf(stderr, "Unable to write to %s -- exiting\n", outFn); exit(1); } } /* Write the new PNG. */ gdImagePng(im, out); if (!useStdinStdout) { fclose(out); /* Erase the old PNG. */ unlink(argv[argc-1]); /* Rename the new to the old. */ if (rename(outFn, argv[argc-1])!=0) { perror("rename"); exit(1); } } } /* Delete the image from memory. */ if (im) { gdImageDestroy(im); } /* All's well that ends well. */ return 0; }
/* draw the gif file, based on the tentry desciption */ void draw_gif ( FILE * gif ) { #define c_blank 245,245,245 /* base colors */ #define c_light 194,194,194 #define c_dark 100,100,100 #define c_black 0,0,0 #define c_white 255,255,0 #define c_blue 0,0,255 #define c_red 255,0,0 #define c_green 0,255,0 gdImagePtr graph; int i_light,i_dark,i_blank, i_black, i_white, i_blue, i_red, i_green; graph = gdImageCreate(xsize, ysize); /* the first color allocated will be the background color. */ i_blank = gdImageColorAllocate(graph,c_blank); i_light = gdImageColorAllocate(graph,c_light); i_dark = gdImageColorAllocate(graph,c_dark); gdImageInterlace(graph, 1); i_black = gdImageColorAllocate(graph,c_black); i_white = gdImageColorAllocate(graph,c_white); i_red = gdImageColorAllocate(graph,c_red); i_green = gdImageColorAllocate(graph,c_green); i_blue = gdImageColorAllocate(graph,c_blue); /* draw the image border */ gdImageLine(graph,0,0,xsize-1,0,i_light); gdImageLine(graph,1,1,xsize-2,1,i_light); gdImageLine(graph,0,0,0,ysize-1,i_light); gdImageLine(graph,1,1,1,ysize-2,i_light); gdImageLine(graph,xsize-1,0,xsize-1,ysize-1,i_dark); gdImageLine(graph,0,ysize-1,xsize-1,ysize-1,i_dark); gdImageLine(graph,xsize-2,1,xsize-2,ysize-2,i_dark); gdImageLine(graph,1,ysize-2,xsize-2,ysize-2,i_dark); { /* date the graph */ struct tm *newtime; time_t aclock; time( &aclock ); /* Get time in seconds */ newtime = localtime( &aclock ); /* Convert time to struct */ /* tm form */ gdImageString(graph, gdFontSmall,gdFontSmall->w,3,asctime( newtime ),i_dark); }; /*i_col = find_color(graph, colortable[pcurrententry->color]); gdImageFilledRectangle(graph, pcurrententry->coords[0], pcurrententry->coords[1], pcurrententry->coords[2], pcurrententry->coords[3],i_col2); } gdImageString(graph, gdFontSmall, pcurrententry->coords[0], pcurrententry->coords[1], pcurrententry->str, i_col ); gdImageStringUp(graph, gdFontSmall, pcurrententry->coords[0], pcurrententry->coords[1], pcurrententry->str, i_col ); gdImagePtr brush_2pix; brush_2pix = gdImageCreate(2,2); gdImageColorAllocate( brush_2pix, r(colortable[colorratetable[pcurrententry->rate]]), g(colortable[colorratetable[pcurrententry->rate]]), b(colortable[colorratetable[pcurrententry->rate]]) ); gdImageSetBrush(graph, brush_2pix); i_col = gdBrushed; gdImageLine(graph, x, y, x2, y2,i_col); gdImageDestroy(brush_2pix);*/ /* draw axes and graphs */ { int w = gdFontSmall->w, h = gdFontSmall->h, i, j, incrx, incry, maxio; char str[20]; #define AXESX (distcount + 1) #define AXESY 6 maxio = 0; for ( i = 0; i < distcount; i ++ ) { if (maxio < dist[i][0]) maxio = dist[i][0]; if (maxio < dist[i][1]) maxio = dist[i][1]; } incry = (ysize-(h*2)-(w*7))/(AXESY-1); incrx = (xsize-(w*9))/(AXESX-1); j = 100; for ( i = h*2; i <= ((h*2) + (incry * (AXESY-1))) ; i+= incry ) { gdImageLine(graph,w*7,i,w*7 + (incrx*(AXESX-1)),i,i_black); /* horizontal */ sprintf ( str, "%3u%%", j ); j-= 100/(AXESY-1); gdImageString(graph, gdFontSmall,w,i-h/2,str,i_black ); } j = 0; for ( i = w*7; i <= ((w*7) + (incrx * (AXESX-1))) ; i+= incrx ) { gdImageLine(graph,i,h*2,i,h*2 + (incry*(AXESY-1)),i_black); /* vertical */ sprintf ( str, "%3u%%", j ); j+= (100/(AXESX-1)); gdImageStringUp(graph, gdFontSmall, i - w/2, ysize - h, str, i_black ); } for ( i = 0; i < distcount; i ++ ) { int x1, x2, y1, y2, mrgx; mrgx = incrx/5; x1 = (w*7) + (i*incrx) + mrgx; x2 = x1 + (incrx/3); y2 = h*2 + (incry*(AXESY-1)) - 2; y1 = y2 - (((ysize-(h*2)-(w*7) - 2) * dist[i][0]) / rounds); /* printf ( "x1 %u, y1 %u, x2 %u, y2 %u.\n", x1, y1, x2, y2 );*/ gdImageFilledRectangle(graph, x1, y1, x2, y2,i_green); gdImageRectangle(graph, x1, y1, x2, y2,i_dark); x2 = (w*7) + ((i+1)*incrx) - mrgx; x1 = x2 - (incrx/3); y2 = h*2 + (incry*(AXESY-1)) - 2; y1 = y2 - (((ysize-(h*2)-(w*7) - 2) * dist[i][1]) / rounds); /* printf ( "x1 %u, y1 %u, x2 %u, y2 %u.\n", x1, y1, x2, y2 );*/ gdImageFilledRectangle(graph, x1, y1, x2, y2,i_blue); gdImageRectangle(graph, x1, y1, x2, y2,i_dark); } } gdImageGif(graph, gif); gdImageDestroy(graph); }
/* draw the gif file */ void draw_distrib_gif ( FILE * score, FILE * gif ) { #define c_blank 245,245,245 /* base colors */ #define c_light 194,194,194 #define c_dark 100,100,100 #define c_black 0,0,0 #define c_white 255,255,0 #define c_blue 0,0,255 #define c_red 255,0,0 #define c_green 0,255,0 gdImagePtr graph; int i_light,i_dark,i_blank, i_black, i_white, i_blue, i_red, i_green; int color[4000][2]; graph = gdImageCreate(xsize, ysize); /* the first color allocated will be the background color. */ i_blank = gdImageColorAllocate(graph,c_blank); i_light = gdImageColorAllocate(graph,c_light); i_dark = gdImageColorAllocate(graph,c_dark); gdImageInterlace(graph, 1); i_black = gdImageColorAllocate(graph,c_black); i_white = gdImageColorAllocate(graph,c_white); i_red = gdImageColorAllocate(graph,c_red); i_green = gdImageColorAllocate(graph,c_green); i_blue = gdImageColorAllocate(graph,c_blue); { int i; for (i = 0; i <= distcount; i++ ) { color[distcount - i - 1][0] = gdImageColorAllocate(graph, (255*i)/distcount, 255, (255*i)/distcount); } for (i = 0; i <= distcount; i++ ) { color[distcount - i - 1][1] = gdImageColorAllocate(graph, (255*i)/distcount, (255*i)/distcount, 255); } } /* draw the image border */ gdImageLine(graph,0,0,xsize-1,0,i_light); gdImageLine(graph,1,1,xsize-2,1,i_light); gdImageLine(graph,0,0,0,ysize-1,i_light); gdImageLine(graph,1,1,1,ysize-2,i_light); gdImageLine(graph,xsize-1,0,xsize-1,ysize-1,i_dark); gdImageLine(graph,0,ysize-1,xsize-1,ysize-1,i_dark); gdImageLine(graph,xsize-2,1,xsize-2,ysize-2,i_dark); gdImageLine(graph,1,ysize-2,xsize-2,ysize-2,i_dark); { /* date the graph */ struct tm *newtime; time_t aclock; time( &aclock ); /* Get time in seconds */ newtime = localtime( &aclock ); /* Convert time to struct */ /* tm form */ gdImageString(graph, gdFontSmall,gdFontSmall->w,3,asctime( newtime ),i_dark); }; /*i_col = find_color(graph, colortable[pcurrententry->color]); gdImageFilledRectangle(graph, pcurrententry->coords[0], pcurrententry->coords[1], pcurrententry->coords[2], pcurrententry->coords[3],i_col2); } gdImageString(graph, gdFontSmall, pcurrententry->coords[0], pcurrententry->coords[1], pcurrententry->str, i_col ); gdImageStringUp(graph, gdFontSmall, pcurrententry->coords[0], pcurrententry->coords[1], pcurrententry->str, i_col ); gdImagePtr brush_2pix; brush_2pix = gdImageCreate(2,2); gdImageColorAllocate( brush_2pix, r(colortable[colorratetable[pcurrententry->rate]]), g(colortable[colorratetable[pcurrententry->rate]]), b(colortable[colorratetable[pcurrententry->rate]]) ); gdImageSetBrush(graph, brush_2pix); i_col = gdBrushed; gdImageLine(graph, x, y, x2, y2,i_col); gdImageDestroy(brush_2pix);*/ /* draw axes and graphs */ { int w = gdFontSmall->w, h = gdFontSmall->h, i, j, k, incrx, incry; char str[4000]; int nbaxesx = (rate + 1); int nbaxesy = 6; int textx = 7; int texty = 15; incry = (ysize-(h*2)-(w*texty))/(nbaxesy-1); incrx = (xsize-(w*(textx+2)))/(nbaxesx-1); j = 100; for ( i = h*2; i <= ((h*2) + (incry * (nbaxesy-1))) ; i+= incry ) { gdImageLine(graph,w*textx,i,w*textx + (incrx*(nbaxesx-1)),i,i_black); /* horizontal */ sprintf ( str, "%3u%%", j ); j-= 100/(nbaxesy-1); gdImageString(graph, gdFontSmall,w,i-h/2,str,i_black ); } j = 0; for ( i = w*7; i <= ((w*7) + (incrx * (nbaxesx-1))) ; i+= incrx ) { /*gdImageLine(graph,i,h*2,i,h*2 + (incry*(AXESY-1)),i_black);*/ /* vertical */ /*sprintf ( str, "%3u%%", j ); j+= (100/(AXESX-1)); gdImageStringUp(graph, gdFontSmall, i - w/2, ysize - h, str, i_black );*/ } for ( i = 0; i < rate; i ++ ) { char *name,*ptr; int tin=0, tout=0; int x1, x2, y1, y2, mrgx; if ( fscanf ( score, "%s", str ) == EOF ) break; /*printf ( "%s\n", str );*/ name = str; if ((ptr = strtok( str, ":")) == NULL) continue; /*printf ( "%s:", name );*/ for ( j = 0; j < distcount; j++ ) { dist[j][0] = dist[j][0] = 0; if ((ptr = strtok( NULL, "/,")) == NULL) continue; dist[j][0] = atoi(ptr); tin += dist[j][0]; if ((ptr = strtok( NULL, "/,")) == NULL) continue; dist[j][1] = atoi(ptr); tout += dist[j][1]; /*printf ( "%u/%u,",dist[j][0],dist[j][1] );*/ } /*printf ( "\n" );*/ /* draw label and graphs */ mrgx = incrx/5; x1 = (w*textx) + (i*incrx) + (incrx/2) - (h/2); y1 = ysize-h; gdImageStringUp( graph, gdFontSmall, x1, y1, str, i_black ); for (k = 0; k < 2; k ++ ) { y1 = ysize-((texty-4) * w); if ( k == 0 ) { x1 = (w*textx) + (i*incrx) + mrgx; x2 = x1 + (incrx/3); gdImageStringUp( graph, gdFontSmall, x1, y1, "in", i_black ); } else { x2 = (w*textx) + ((i+1)*incrx) - mrgx; x1 = x2 - (incrx/3); gdImageStringUp( graph, gdFontSmall, x1, y1, "out", i_black ); } y2 = h*2 + (incry*(nbaxesy-1)); for ( j = distcount-1; j >=0 ; j-- ) { y1 = y2 - (((ysize-(h*2)-(w*texty) - 2) * dist[j][k]) / tin); if (j == 0) { /* 'correct' cumulative error */ y1 = h*2; } gdImageFilledRectangle(graph, x1, y1, x2, y2,color[j][k]); gdImageRectangle(graph, x1, y1, x2, y2,i_black); y2 = y1; } } /* int x1, x2, y1, y2, mrgx; mrgx = incrx/5; x1 = (w*7) + (i*incrx) + mrgx; x2 = x1 + (incrx/3); y2 = h*2 + (incry*(AXESY-1)) - 2; y1 = y2 - (((ysize-(h*2)-(w*7) - 2) * dist[i][0]) / rounds); gdImageFilledRectangle(graph, x1, y1, x2, y2,i_green); gdImageRectangle(graph, x1, y1, x2, y2,i_dark); x2 = (w*7) + ((i+1)*incrx) - mrgx; x1 = x2 - (incrx/3); y2 = h*2 + (incry*(AXESY-1)) - 2; y1 = y2 - (((ysize-(h*2)-(w*7) - 2) * dist[i][1]) / rounds); gdImageFilledRectangle(graph, x1, y1, x2, y2,i_blue); gdImageRectangle(graph, x1, y1, x2, y2,i_dark); */ } } gdImageGif(graph, gif); gdImageDestroy(graph); }
// Generates the count image from the count string, returns true if all ok bool CreateImage(const char *pcCount, const char *pcFont, int iDigits) { // Set the spare value int iCountLen = strlen(pcCount); if (iDigits < iCountLen) iDigits = iCountLen; int iSpare = 0; if (iDigits > iCountLen) iSpare = iDigits - iCountLen; // Loop vars char pcDigitName[STR_SIZE] = ""; gdImagePtr pImg = NULL; FILE *pPic = NULL; // Load the zero digit image sprintf(pcDigitName, COUNTER_ZERO, pcFont); pPic = fopen(pcDigitName, "rb+"); if (pPic == NULL) return false; pImg = gdImageCreateFromGif(pPic); fclose(pPic); if (pImg == NULL) return false; // Create the output image gdImagePtr pOutImg = NULL; pOutImg = gdImageCreate(iDigits * pImg->sx, pImg->sy); if (pOutImg == NULL) { gdImageDestroy(pImg); return false; } // Copy the palette info from one to the other... int iColTotal = gdImageColorsTotal(pImg); for (int i = 0; i < iColTotal; i++) { gdImageColorAllocate(pOutImg, gdImageRed(pImg, i), gdImageGreen(pImg, i), gdImageBlue(pImg, i)); } int iTransCol = gdImageGetTransparent(pImg); if (iTransCol >= 0) { gdImageColorTransparent(pOutImg, iTransCol); gdImageFill(pOutImg, 0, 0, iTransCol); } // Loop through each leading zero int iPos = 0; while (iSpare-- > 0) { // paste in the image gdImageCopy(pOutImg, pImg, iPos, 0, 0, 0, pImg->sx, pImg->sy); iPos += pImg->sx; } // Delete the zero image gdImageDestroy(pImg); // Loop through each counter character const char *pcPos = pcCount; while (*pcPos != '\0') { sprintf(pcDigitName, COUNTER_PIC, pcFont, *pcPos); // Load the image pPic = fopen(pcDigitName, "rb+"); if (pPic == NULL) { gdImageDestroy(pOutImg); return false; } pImg = gdImageCreateFromGif(pPic); if (pImg == NULL) { gdImageDestroy(pOutImg); return false; } // Paste in the image gdImageCopy(pOutImg, pImg, iPos, 0, 0, 0, pImg->sx, pImg->sy); iPos += pImg->sx; // Delete the image gdImageDestroy(pImg); // Update the position counter pcPos++; } // Write out the output image if (g_oCGI.Debug()) { char pcGIFName[STR_SIZE] = COUNTER_ROOT; strcat(pcGIFName, "out.gif"); FILE *pGIFFile = NULL; pGIFFile = fopen(pcGIFName, "wb"); if (pGIFFile) { gdImageGif(pOutImg, pGIFFile); fclose(pGIFFile); } } else { gdImageInterlace(pOutImg, 1); #ifdef WIN32 _setmode(_fileno(stdout), _O_BINARY); #endif printf("Content-type: image/gif\n\n"); gdImageGif(pOutImg, stdout); } // Destroy the image gdImageDestroy(pOutImg); return true; } // CreateImage
int create_png_range(const freq_range_t rx_range_list[], const freq_range_t tx_range_list[], int num) { FILE *out; /* Input and output images */ gdImagePtr im_rng; char rng_fname[128]; /* Color indexes */ #if 0 int white; #endif int black; int rx_rgb, tx_rgb; /* Create output image, x by y pixels. */ im_rng = gdImageCreate(RANGE_WIDTH + IM_LGD, UHF_H + RANGE_HEIGHT); /* First color allocated is background. */ // white = gdImageColorAllocate(im_rng, 255, 255, 255); gdImageColorAllocate(im_rng, 255, 255, 255); black = gdImageColorAllocate(im_rng, 0, 0, 0); #if 0 /* Set transparent color. */ gdImageColorTransparent(im_rng, white); #endif /* Try to load demoin.png and paste part of it into the output image. */ tx_rgb = gdImageColorAllocate(im_rng, TX_R, TX_G, TX_B); rx_rgb = gdImageColorAllocate(im_rng, RX_R, RX_G, RX_B); draw_range(rx_range_list, im_rng, 0, RANGE_MIDHEIGHT - 1, rx_rgb); draw_range(tx_range_list, im_rng, RANGE_MIDHEIGHT, RANGE_HEIGHT - 1, tx_rgb); gdImageRectangle(im_rng, IM_LGD, HF_H, IM_LGD + RANGE_WIDTH - 1, HF_H + RANGE_HEIGHT - 1, black); gdImageRectangle(im_rng, IM_LGD, VHF_H, IM_LGD + RANGE_WIDTH - 1, VHF_H + RANGE_HEIGHT - 1, black); gdImageRectangle(im_rng, IM_LGD, UHF_H, IM_LGD + RANGE_WIDTH - 1, UHF_H + RANGE_HEIGHT - 1, black); /* gdImageStringUp */ gdImageString(im_rng, gdFontSmall, 1, HF_H + 1, (unsigned char *) "HF", black); gdImageString(im_rng, gdFontSmall, 1, VHF_H + 1, (unsigned char *) "VHF", black); gdImageString(im_rng, gdFontSmall, 1, UHF_H + 1, (unsigned char *) "UHF", black); /* Make output image interlaced (allows "fade in" in some viewers, and in the latest web browsers) */ gdImageInterlace(im_rng, 1); sprintf(rng_fname, "range%d.png", num); out = fopen(rng_fname, "wb"); /* Write PNG */ gdImagePng(im_rng, out); fclose(out); gdImageDestroy(im_rng); return 0; }
/* * Create a gd-format image from the JPEG-format INFILE. Returns the * image, or NULL upon error. */ gdImagePtr gdImageCreateFromJpegCtx(gdIOCtx *infile) { struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; jmpbuf_wrapper jmpbufw; /* volatile so we can gdFree them after longjmp */ volatile JSAMPROW row = 0; volatile gdImagePtr im = 0; JSAMPROW rowptr[1]; int i, j, retval; JDIMENSION nrows; #ifdef JPEG_DEBUG printf("gd-jpeg: gd JPEG version %s\n", GD_JPEG_VERSION); printf("gd-jpeg: JPEG library version %d, %d-bit sample values\n", JPEG_LIB_VERSION, BITS_IN_JSAMPLE); #endif memset(&cinfo, 0, sizeof(cinfo)); memset(&jerr, 0, sizeof(jerr)); cinfo.err = jpeg_std_error(&jerr); cinfo.client_data = &jmpbufw; if (setjmp(jmpbufw.jmpbuf) != 0) { /* we're here courtesy of longjmp */ if (row) gdFree(row); if (im) gdImageDestroy(im); return 0; } cinfo.err->error_exit = fatal_jpeg_error; jpeg_create_decompress(&cinfo); jpeg_gdIOCtx_src(&cinfo, infile); retval = jpeg_read_header(&cinfo, TRUE); if (retval != JPEG_HEADER_OK) fprintf(stderr, "gd-jpeg: warning: jpeg_read_header returns" " %d, expected %d\n", retval, JPEG_HEADER_OK); if (cinfo.image_height > INT_MAX) fprintf(stderr, "gd-jpeg: warning: JPEG image height (%u) is" " greater than INT_MAX (%d) (and thus greater than" " gd can handle)", cinfo.image_height, INT_MAX); if (cinfo.image_width > INT_MAX) fprintf(stderr, "gd-jpeg: warning: JPEG image width (%u) is" " greater than INT_MAX (%d) (and thus greater than" " gd can handle)\n", cinfo.image_width, INT_MAX); im = gdImageCreate((int)cinfo.image_width, (int)cinfo.image_height); if (im == 0) { fprintf(stderr, "gd-jpeg error: cannot allocate gdImage" " struct\n"); goto error; } /* * Have the JPEG library quantize the number of image colors to * 256 maximum; force into RGB colorspace */ cinfo.out_color_space = JCS_RGB; cinfo.quantize_colors = TRUE; cinfo.desired_number_of_colors = gdMaxColors; if (jpeg_start_decompress(&cinfo) != TRUE) fprintf(stderr, "gd-jpeg: warning: jpeg_start_decompress" " reports suspended data source\n"); #ifdef JPEG_DEBUG printf("gd-jpeg: JPEG image information:"); if (cinfo.saw_JFIF_marker) printf(" JFIF version %d.%.2d", (int)cinfo.JFIF_major_version, (int)cinfo.JFIF_minor_version); else if (cinfo.saw_Adobe_marker) printf(" Adobe format"); else printf(" UNKNOWN format"); printf(" %ux%u (raw) / %ux%u (scaled) %d-bit", cinfo.image_width, cinfo.image_height, cinfo.output_width, cinfo.output_height, cinfo.data_precision); printf(" %s", (cinfo.progressive_mode ? "progressive" : "baseline")); printf(" image, %d quantized colors, ", cinfo.actual_number_of_colors); switch (cinfo.jpeg_color_space) { case JCS_GRAYSCALE: printf("grayscale"); break; case JCS_RGB: printf("RGB"); break; case JCS_YCbCr: printf("YCbCr (a.k.a. YUV)"); break; case JCS_CMYK: printf("CMYK"); break; case JCS_YCCK: printf("YCbCrK"); break; default: printf("UNKNOWN (value: %d)", (int)cinfo.jpeg_color_space); break; } printf(" colorspace\n"); fflush(stdout); #endif /* JPEG_DEBUG */ gdImageInterlace(im, cinfo.progressive_mode != 0); im->colorsTotal = cinfo.actual_number_of_colors; if (cinfo.output_components != 1) { fprintf(stderr, "gd-jpeg: error: JPEG color quantization" " request resulted in output_components == %d" " (expected 1)\n", cinfo.output_components); goto error; } for (i = 0; i < im->colorsTotal; i++) { #if BITS_IN_JSAMPLE == 8 im->red[i] = cinfo.colormap[0][i]; im->green[i] = cinfo.colormap[1][i]; im->blue[i] = cinfo.colormap[2][i]; #elif BITS_IN_JSAMPLE == 12 im->red[i] = (cinfo.colormap[0][i] >> 4) & 0xff; im->green[i] = (cinfo.colormap[1][i] >> 4) & 0xff; im->blue[i] = (cinfo.colormap[2][i] >> 4) & 0xff; #else #error IJG JPEG library BITS_IN_JSAMPLE value must be 8 or 12 #endif im->open[i] = 0; #ifdef JPEG_DEBUG printf("gd-jpeg: gd colormap index %d set to (%d, %d, %d)\n", i, im->red[i], im->green[i], im->blue[i]); #endif } row = gdCalloc(cinfo.output_width, sizeof(JSAMPLE)); if (row == 0) { fprintf(stderr, "gd-jpeg: error: unable to allocate row for" " JPEG scanline: gdCalloc returns NULL\n"); goto error; } rowptr[0] = row; for (i = 0; i < cinfo.output_height; i++) { nrows = jpeg_read_scanlines(&cinfo, rowptr, 1); if (nrows != 1) { fprintf(stderr, "gd-jpeg: error: jpeg_read_scanlines" " returns %u, expected 1\n", nrows); goto error; } for (j = 0; j < cinfo.output_width; j++) im->pixels[i][j] = row[j]; } if (jpeg_finish_decompress(&cinfo) != TRUE) fprintf(stderr, "gd-jpeg: warning: jpeg_finish_decompress" " reports suspended data source\n"); jpeg_destroy_decompress(&cinfo); gdFree(row); return im; error: jpeg_destroy_decompress(&cinfo); if (row) gdFree(row); if (im) gdImageDestroy(im); return 0; }