]> granicus.if.org Git - php/commitdiff
Port variable image resolution support from libgd 2.1.0
authorChristoph M. Becker <cmbecker69@gmx.de>
Mon, 19 Sep 2016 17:00:58 +0000 (19:00 +0200)
committerChristoph M. Becker <cmbecker69@gmx.de>
Mon, 19 Sep 2016 17:00:58 +0000 (19:00 +0200)
The PHP binding for this feature will be submitted as a separate PR.

ext/gd/libgd/gd.c
ext/gd/libgd/gd.h
ext/gd/libgd/gd_jpeg.c
ext/gd/libgd/gd_png.c
ext/gd/libgd/gdhelpers.h

index 7a0af8de9209c259d07547917dbf86a19b5630a5..dd38a11cb9d8f33966f83436e62cef0a0b9b18b4 100644 (file)
@@ -170,6 +170,8 @@ gdImagePtr gdImageCreate (int sx, int sy)
        im->cy1 = 0;
        im->cx2 = im->sx - 1;
        im->cy2 = im->sy - 1;
+       im->res_x = GD_RESOLUTION;
+       im->res_y = GD_RESOLUTION;
        im->interpolation = NULL;
        im->interpolation_id = GD_BILINEAR_FIXED;
        return im;
@@ -225,6 +227,8 @@ gdImagePtr gdImageCreateTrueColor (int sx, int sy)
        im->cy1 = 0;
        im->cx2 = im->sx - 1;
        im->cy2 = im->sy - 1;
+       im->res_x = GD_RESOLUTION;
+       im->res_y = GD_RESOLUTION;
        im->interpolation = NULL;
        im->interpolation_id = GD_BILINEAR_FIXED;
        return im;
@@ -3056,6 +3060,12 @@ void gdImageGetClip (gdImagePtr im, int *x1P, int *y1P, int *x2P, int *y2P)
        *y2P = im->cy2;
 }
 
+void gdImageSetResolution(gdImagePtr im, const unsigned int res_x, const unsigned int res_y)
+{
+       if (res_x > 0) im->res_x = res_x;
+       if (res_y > 0) im->res_y = res_y;
+}
+
 /* convert a palette image to true color */
 int gdImagePaletteToTrueColor(gdImagePtr src)
 {
index 2eb4fd8e1cbff90a754ba0c70b73e809baf46d93..251dbfb0be691cd194231afd4714d57b9baa0397 100644 (file)
@@ -253,6 +253,8 @@ typedef struct gdImageStruct {
        int cy1;
        int cx2;
        int cy2;
+       unsigned int res_x;
+       unsigned int res_y;
        gdInterpolationMethod interpolation_id;
        interpolation_method interpolation;
 } gdImage;
@@ -433,6 +435,7 @@ void gdImageRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color);
 void gdImageFilledRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color);
 void gdImageSetClip(gdImagePtr im, int x1, int y1, int x2, int y2);
 void gdImageGetClip(gdImagePtr im, int *x1P, int *y1P, int *x2P, int *y2P);
+void gdImageSetResolution(gdImagePtr im, const unsigned int res_x, const unsigned int res_y);
 void gdImageChar(gdImagePtr im, gdFontPtr f, int x, int y, int c, int color);
 void gdImageCharUp(gdImagePtr im, gdFontPtr f, int x, int y, int c, int color);
 void gdImageString(gdImagePtr im, gdFontPtr f, int x, int y, unsigned char *s, int color);
@@ -746,6 +749,8 @@ int gdImagePixelate(gdImagePtr im, int block_size, const unsigned int mode);
        of image is also your responsibility. */
 #define gdImagePalettePixel(im, x, y) (im)->pixels[(y)][(x)]
 #define gdImageTrueColorPixel(im, x, y) (im)->tpixels[(y)][(x)]
+#define gdImageResolutionX(im) (im)->res_x
+#define gdImageResolutionY(im) (im)->res_y
 
 /* I/O Support routines. */
 
index f239ef8acdd24f27e1f72bbab4166f9dcda659e7..900b13504c09248d6c340045499dff0f292b2a40 100644 (file)
@@ -195,6 +195,11 @@ void gdImageJpegCtx (gdImagePtr im, gdIOCtx * outfile, int quality)
        cinfo.input_components = 3;     /* # of color components per pixel */
        cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
        jpeg_set_defaults (&cinfo);
+
+       cinfo.density_unit = 1;
+       cinfo.X_density = im->res_x;
+       cinfo.Y_density = im->res_y;
+
        if (quality >= 0) {
                jpeg_set_quality (&cinfo, quality, TRUE);
        }
@@ -381,6 +386,18 @@ gdImagePtr gdImageCreateFromJpegCtxEx (gdIOCtx * infile, int ignore_warning)
                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. */
index a012cc63b8ce4b24249e99d007b906cbb55e3ae2..b521e45da4011c472c9425585be47b9dc3fcb635 100644 (file)
@@ -120,8 +120,8 @@ gdImagePtr gdImageCreateFromPngCtx (gdIOCtx * infile)
 #endif
        png_structp png_ptr;
        png_infop info_ptr;
-       png_uint_32 width, height, rowbytes, w, h;
-       int bit_depth, color_type, interlace_type;
+       png_uint_32 width, height, rowbytes, w, h, res_x, res_y;
+       int bit_depth, color_type, interlace_type, unit_type;
        int num_palette, num_trans;
        png_colorp palette;
        png_color_16p trans_gray_rgb;
@@ -226,6 +226,20 @@ gdImagePtr gdImageCreateFromPngCtx (gdIOCtx * infile)
        }
 #endif
 
+#ifdef PNG_pHYs_SUPPORTED
+       /* check if the resolution is specified */
+       if (png_get_valid(png_ptr, info_ptr, PNG_INFO_pHYs)) {
+               if (png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y, &unit_type)) {
+                       switch (unit_type) {
+                       case PNG_RESOLUTION_METER:
+                               im->res_x = DPM2DPI(res_x);
+                               im->res_y = DPM2DPI(res_y);
+                               break;
+                       }
+               }
+       }
+#endif
+
        switch (color_type) {
                case PNG_COLOR_TYPE_PALETTE:
                        png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
@@ -526,6 +540,12 @@ void gdImagePngCtxEx (gdImagePtr im, gdIOCtx * outfile, int level, int basefilte
                png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, basefilter);
        }
 
+#ifdef PNG_pHYs_SUPPORTED
+       /* 2.1.0: specify the resolution */
+       png_set_pHYs(png_ptr, info_ptr, DPI2DPM(im->res_x), DPI2DPM(im->res_y),
+                    PNG_RESOLUTION_METER);
+#endif
+
        /* can set this to a smaller value without compromising compression if all
         * image data is 16K or less; will save some decoder memory [min == 8]
         */
index 768fde93b866b5bdb0acfa3796ce7417d8b44c6a..afb45f0e67de87ef984cea049ad4667ce460cf2f 100644 (file)
@@ -42,5 +42,10 @@ int overflow2(int a, int b);
 #define gdMutexUnlock(x)
 #endif
 
+#define DPCM2DPI(dpcm) (unsigned int)((dpcm)*2.54 + 0.5)
+#define DPM2DPI(dpm)   (unsigned int)((dpm)*0.0254 + 0.5)
+#define DPI2DPCM(dpi)  (unsigned int)((dpi)/2.54 + 0.5)
+#define DPI2DPM(dpi)   (unsigned int)((dpi)/0.0254 + 0.5)
+
 #endif /* GDHELPERS_H */