Skip to content

Commit 932c20f

Browse files
committed
Port variable image resolution support from libgd 2.1.0
The PHP binding for this feature will be submitted as a separate PR.
1 parent 77ba248 commit 932c20f

File tree

5 files changed

+59
-2
lines changed

5 files changed

+59
-2
lines changed

ext/gd/libgd/gd.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,8 @@ gdImagePtr gdImageCreate (int sx, int sy)
170170
im->cy1 = 0;
171171
im->cx2 = im->sx - 1;
172172
im->cy2 = im->sy - 1;
173+
im->res_x = GD_RESOLUTION;
174+
im->res_y = GD_RESOLUTION;
173175
im->interpolation = NULL;
174176
im->interpolation_id = GD_BILINEAR_FIXED;
175177
return im;
@@ -225,6 +227,8 @@ gdImagePtr gdImageCreateTrueColor (int sx, int sy)
225227
im->cy1 = 0;
226228
im->cx2 = im->sx - 1;
227229
im->cy2 = im->sy - 1;
230+
im->res_x = GD_RESOLUTION;
231+
im->res_y = GD_RESOLUTION;
228232
im->interpolation = NULL;
229233
im->interpolation_id = GD_BILINEAR_FIXED;
230234
return im;
@@ -3056,6 +3060,12 @@ void gdImageGetClip (gdImagePtr im, int *x1P, int *y1P, int *x2P, int *y2P)
30563060
*y2P = im->cy2;
30573061
}
30583062

3063+
void gdImageSetResolution(gdImagePtr im, const unsigned int res_x, const unsigned int res_y)
3064+
{
3065+
if (res_x > 0) im->res_x = res_x;
3066+
if (res_y > 0) im->res_y = res_y;
3067+
}
3068+
30593069
/* convert a palette image to true color */
30603070
int gdImagePaletteToTrueColor(gdImagePtr src)
30613071
{

ext/gd/libgd/gd.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,8 @@ typedef struct gdImageStruct {
253253
int cy1;
254254
int cx2;
255255
int cy2;
256+
unsigned int res_x;
257+
unsigned int res_y;
256258
gdInterpolationMethod interpolation_id;
257259
interpolation_method interpolation;
258260
} gdImage;
@@ -433,6 +435,7 @@ void gdImageRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color);
433435
void gdImageFilledRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color);
434436
void gdImageSetClip(gdImagePtr im, int x1, int y1, int x2, int y2);
435437
void gdImageGetClip(gdImagePtr im, int *x1P, int *y1P, int *x2P, int *y2P);
438+
void gdImageSetResolution(gdImagePtr im, const unsigned int res_x, const unsigned int res_y);
436439
void gdImageChar(gdImagePtr im, gdFontPtr f, int x, int y, int c, int color);
437440
void gdImageCharUp(gdImagePtr im, gdFontPtr f, int x, int y, int c, int color);
438441
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);
746749
of image is also your responsibility. */
747750
#define gdImagePalettePixel(im, x, y) (im)->pixels[(y)][(x)]
748751
#define gdImageTrueColorPixel(im, x, y) (im)->tpixels[(y)][(x)]
752+
#define gdImageResolutionX(im) (im)->res_x
753+
#define gdImageResolutionY(im) (im)->res_y
749754

750755
/* I/O Support routines. */
751756

ext/gd/libgd/gd_jpeg.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,11 @@ void gdImageJpegCtx (gdImagePtr im, gdIOCtx * outfile, int quality)
195195
cinfo.input_components = 3; /* # of color components per pixel */
196196
cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
197197
jpeg_set_defaults (&cinfo);
198+
199+
cinfo.density_unit = 1;
200+
cinfo.X_density = im->res_x;
201+
cinfo.Y_density = im->res_y;
202+
198203
if (quality >= 0) {
199204
jpeg_set_quality (&cinfo, quality, TRUE);
200205
}
@@ -381,6 +386,18 @@ gdImagePtr gdImageCreateFromJpegCtxEx (gdIOCtx * infile, int ignore_warning)
381386
goto error;
382387
}
383388

389+
/* check if the resolution is specified */
390+
switch (cinfo.density_unit) {
391+
case 1:
392+
im->res_x = cinfo.X_density;
393+
im->res_y = cinfo.Y_density;
394+
break;
395+
case 2:
396+
im->res_x = DPCM2DPI(cinfo.X_density);
397+
im->res_y = DPCM2DPI(cinfo.Y_density);
398+
break;
399+
}
400+
384401
/* 2.0.22: very basic support for reading CMYK colorspace files. Nice for
385402
* thumbnails but there's no support for fussy adjustment of the
386403
* assumed properties of inks and paper. */

ext/gd/libgd/gd_png.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@ gdImagePtr gdImageCreateFromPngCtx (gdIOCtx * infile)
120120
#endif
121121
png_structp png_ptr;
122122
png_infop info_ptr;
123-
png_uint_32 width, height, rowbytes, w, h;
124-
int bit_depth, color_type, interlace_type;
123+
png_uint_32 width, height, rowbytes, w, h, res_x, res_y;
124+
int bit_depth, color_type, interlace_type, unit_type;
125125
int num_palette, num_trans;
126126
png_colorp palette;
127127
png_color_16p trans_gray_rgb;
@@ -226,6 +226,20 @@ gdImagePtr gdImageCreateFromPngCtx (gdIOCtx * infile)
226226
}
227227
#endif
228228

229+
#ifdef PNG_pHYs_SUPPORTED
230+
/* check if the resolution is specified */
231+
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_pHYs)) {
232+
if (png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y, &unit_type)) {
233+
switch (unit_type) {
234+
case PNG_RESOLUTION_METER:
235+
im->res_x = DPM2DPI(res_x);
236+
im->res_y = DPM2DPI(res_y);
237+
break;
238+
}
239+
}
240+
}
241+
#endif
242+
229243
switch (color_type) {
230244
case PNG_COLOR_TYPE_PALETTE:
231245
png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
@@ -526,6 +540,12 @@ void gdImagePngCtxEx (gdImagePtr im, gdIOCtx * outfile, int level, int basefilte
526540
png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, basefilter);
527541
}
528542

543+
#ifdef PNG_pHYs_SUPPORTED
544+
/* 2.1.0: specify the resolution */
545+
png_set_pHYs(png_ptr, info_ptr, DPI2DPM(im->res_x), DPI2DPM(im->res_y),
546+
PNG_RESOLUTION_METER);
547+
#endif
548+
529549
/* can set this to a smaller value without compromising compression if all
530550
* image data is 16K or less; will save some decoder memory [min == 8]
531551
*/

ext/gd/libgd/gdhelpers.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,10 @@ int overflow2(int a, int b);
4242
#define gdMutexUnlock(x)
4343
#endif
4444

45+
#define DPCM2DPI(dpcm) (unsigned int)((dpcm)*2.54 + 0.5)
46+
#define DPM2DPI(dpm) (unsigned int)((dpm)*0.0254 + 0.5)
47+
#define DPI2DPCM(dpi) (unsigned int)((dpi)/2.54 + 0.5)
48+
#define DPI2DPM(dpi) (unsigned int)((dpi)/0.0254 + 0.5)
49+
4550
#endif /* GDHELPERS_H */
4651

0 commit comments

Comments
 (0)