Commits

Anonymous committed f40454c

ref FS#176: added support of variable resolution by Alan Boudreault.

Comments (0)

Files changed (12)

 GD HEAD
 169, gdColorMapLookup() answers the RGB values according to given color map
      (Takeshi Abe)
+176, Added support of variable resolution by Alan Boudreault (Takeshi Abe)
 184, new filter gdImagePixelate() by Kalle Sommer Nielsen (Takeshi Abe)
 
 GD 2.0.36 (2007-11-xx)
   im->cy1 = 0;
   im->cx2 = im->sx - 1;
   im->cy2 = im->sy - 1;
+  im->res_x = GD_RESOLUTION;
+  im->res_y = GD_RESOLUTION;
   return im;
 }
 
   im->cy1 = 0;
   im->cx2 = im->sx - 1;
   im->cy2 = im->sy - 1;
+  im->res_x = GD_RESOLUTION;
+  im->res_y = GD_RESOLUTION;
   return im;
 }
 
   *y2P = im->cy2;
 }
 
+BGD_DECLARE(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;
+}
+
 /*
  * Added on 2003/12 by Pierre-Alain Joye (pajoye@pearfr.org)
  * */
     int cy1;
     int cx2;
     int cy2;
+
+    /* 2.1.0: allows to specify resolution in dpi */
+    unsigned int res_x;
+    unsigned int res_y;
   }
   gdImage;
 
 			       int color);
 BGD_DECLARE(void) gdImageSetClip(gdImagePtr im, int x1, int y1, int x2, int y2);
 BGD_DECLARE(void) gdImageGetClip(gdImagePtr im, int *x1P, int *y1P, int *x2P, int *y2P);
+BGD_DECLARE(void) gdImageSetResolution(gdImagePtr im, const unsigned int res_x, const unsigned int res_y);
 BGD_DECLARE(int) gdImageBoundsSafe (gdImagePtr im, int x, int y);
 BGD_DECLARE(void) gdImageChar (gdImagePtr im, gdFontPtr f, int x, int y, int c,
 		    int color);
 #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. */
 
 BGD_DECLARE(gdIOCtx *) gdNewFileCtx (FILE *);
 #define GD_CMP_INTERLACE	128	/* Interlaced setting */
 #define GD_CMP_TRUECOLOR	256	/* Truecolor vs palette differs */
 
-/* resolution affects ttf font rendering, particularly hinting */
-#define GD_RESOLUTION           96	/* pixels per inch */
+#define GD_RESOLUTION           96	/* dots per inch */
 
 #ifdef __cplusplus
 }
 
 	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);
 	}
 		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.
 	png_byte sig[8];
 	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;
 	}
 #endif
 
+	/* 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;
+			}
+		}
+	}
+
 	switch (color_type) {
 		case PNG_COLOR_TYPE_PALETTE:
 			png_get_PLTE (png_ptr, info_ptr, &palette, &num_palette);
 	/* 2.0.12: this is finally a parameter */
 	png_set_compression_level (png_ptr, level);
 
+	/* 2.1.0: specify the resolution */
+	png_set_pHYs(png_ptr, info_ptr, DPI2DPM(im->res_x), DPI2DPM(im->res_y),
+				 PNG_RESOLUTION_METER);
+
 	/* 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] */
 	/*  png_set_compression_window_bits(png_ptr, 15);  */
 #endif /* HAVE_PTHREAD */
 #endif /* WIN32 */
 
+#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 */
 
 #ifdef __cplusplus

tests/jpeg/CMakeLists.txt

 SET(TESTS_FILES
 	jpeg_read
 	jpeg_empty_file
+	jpeg_resolution
 )
 
 FOREACH(test_name ${TESTS_FILES})

tests/jpeg/Makefile.am

 ## Process this file with automake to produce Makefile.in -*-Makefile-*-
 
-EXTRA_DIST = CMakeLists.txt conv_test_exp.png conv_test.jpeg empty.jpeg jpeg_empty_file.c jpeg_read.c
+EXTRA_DIST = CMakeLists.txt conv_test_exp.png conv_test.jpeg empty.jpeg jpeg_empty_file.c jpeg_read.c jpeg_resolution.c

tests/jpeg/jpeg_resolution.c

+#include "gd.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "gdtest.h"
+
+int main()
+{
+	gdImagePtr im;
+	void *data;
+	int size, red;
+
+	im = gdImageCreate(100, 100);
+	gdImageSetResolution(im, 72, 300);
+	red = gdImageColorAllocate(im, 0xFF, 0x00, 0x00);
+	gdImageFilledRectangle(im, 0, 0, 99, 99, red);
+	data = gdImageJpegPtr(im, &size, 10);
+	gdImageDestroy(im);
+
+	im = gdImageCreateFromJpegPtr(size, data);
+	gdTestAssert(gdImageResolutionX(im) == 72);
+	gdTestAssert(gdImageResolutionY(im) == 300);
+	gdImageDestroy(im);
+	return 0;
+}

tests/png/CMakeLists.txt

 
 SET(TESTS_FILES
+	png_resolution
 	bug00011
 	bug00033
 	bug00086

tests/png/Makefile.am

 ## Process this file with automake to produce Makefile.in -*-Makefile-*-
 
-EXTRA_DIST = CMakeLists.txt bug00011.c bug00033.png bug00088_1_exp.png bug00088_2_exp.png bug00088.c bug00033.c bug00086.c bug00088_1.png bug00088_2.png emptyfile
+EXTRA_DIST = CMakeLists.txt bug00011.c bug00033.png bug00088_1_exp.png bug00088_2_exp.png bug00088.c bug00033.c bug00086.c bug00088_1.png bug00088_2.png emptyfile png_resolution.c

tests/png/png_resolution.c

+#include "gd.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "gdtest.h"
+
+int main()
+{
+	gdImagePtr im;
+	void *data;
+	int size, red;
+
+	im = gdImageCreate(100, 100);
+	gdImageSetResolution(im, 72, 300);
+	red = gdImageColorAllocate(im, 0xFF, 0x00, 0x00);
+	gdImageFilledRectangle(im, 0, 0, 99, 99, red);
+	data = gdImagePngPtr(im, &size);
+	gdImageDestroy(im);
+
+	im = gdImageCreateFromPngPtr(size, data);
+	gdTestAssert(gdImageResolutionX(im) == 72);
+	gdTestAssert(gdImageResolutionY(im) == 300);
+	gdImageDestroy(im);
+	return 0;
+}