summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/gd/libgd/gd.c10
-rw-r--r--ext/gd/libgd/gd.h5
-rw-r--r--ext/gd/libgd/gd_jpeg.c17
-rw-r--r--ext/gd/libgd/gd_png.c24
-rw-r--r--ext/gd/libgd/gdhelpers.h5
5 files changed, 59 insertions, 2 deletions
diff --git a/ext/gd/libgd/gd.c b/ext/gd/libgd/gd.c
index 7a0af8de92..dd38a11cb9 100644
--- a/ext/gd/libgd/gd.c
+++ b/ext/gd/libgd/gd.c
@@ -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)
{
diff --git a/ext/gd/libgd/gd.h b/ext/gd/libgd/gd.h
index 2eb4fd8e1c..251dbfb0be 100644
--- a/ext/gd/libgd/gd.h
+++ b/ext/gd/libgd/gd.h
@@ -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. */
diff --git a/ext/gd/libgd/gd_jpeg.c b/ext/gd/libgd/gd_jpeg.c
index f239ef8acd..900b13504c 100644
--- a/ext/gd/libgd/gd_jpeg.c
+++ b/ext/gd/libgd/gd_jpeg.c
@@ -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. */
diff --git a/ext/gd/libgd/gd_png.c b/ext/gd/libgd/gd_png.c
index a012cc63b8..b521e45da4 100644
--- a/ext/gd/libgd/gd_png.c
+++ b/ext/gd/libgd/gd_png.c
@@ -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]
*/
diff --git a/ext/gd/libgd/gdhelpers.h b/ext/gd/libgd/gdhelpers.h
index 768fde93b8..afb45f0e67 100644
--- a/ext/gd/libgd/gdhelpers.h
+++ b/ext/gd/libgd/gdhelpers.h
@@ -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 */