diff options
author | Campbell Barton <ideasman42@gmail.com> | 2011-05-13 18:27:12 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2011-05-13 18:27:12 +0400 |
commit | 05d004fd14876d9df0ca1028f77bebcad1580eff (patch) | |
tree | 2027a9e302367a58e8ac02cb6a2c032f3cb594d5 /source | |
parent | 6786f92fe569cbed1ad9fbc12392cc54a3eb58d0 (diff) |
support for reading/writing image resolution (dpi), for PNG and TIFF,
only RNA access currently 'image.resolution'.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/imbuf/IMB_imbuf_types.h | 3 | ||||
-rw-r--r-- | source/blender/imbuf/intern/allocimbuf.c | 1 | ||||
-rw-r--r-- | source/blender/imbuf/intern/png.c | 18 | ||||
-rw-r--r-- | source/blender/imbuf/intern/tiff.c | 39 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_image.c | 36 |
5 files changed, 93 insertions, 4 deletions
diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h index 52afe2ed854..5717a92db54 100644 --- a/source/blender/imbuf/IMB_imbuf_types.h +++ b/source/blender/imbuf/IMB_imbuf_types.h @@ -93,6 +93,9 @@ typedef struct ImBuf { char profile_filename[256]; /* to be implemented properly, specific filename for custom profiles */ #endif + /* resolution - pixels per meter */ + double ppm[2]; + /* tiled pixel storage */ int tilex, tiley; int xtiles, ytiles; diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c index efa37aa1196..91583f02a49 100644 --- a/source/blender/imbuf/intern/allocimbuf.c +++ b/source/blender/imbuf/intern/allocimbuf.c @@ -348,6 +348,7 @@ ImBuf *IMB_allocImBuf(unsigned int x, unsigned int y, uchar d, unsigned int flag ibuf->depth= d; ibuf->ftype= TGA; ibuf->channels= 4; /* float option, is set to other values when buffers get assigned */ + ibuf->ppm[0]= ibuf->ppm[1]= 150.0 / 0.0254; /* 150dpi -> pixels-per-meter */ if(flags & IB_rect) { if(imb_addrectImBuf(ibuf)==FALSE) { diff --git a/source/blender/imbuf/intern/png.c b/source/blender/imbuf/intern/png.c index 200ff0af9af..6b6dcdb88af 100644 --- a/source/blender/imbuf/intern/png.c +++ b/source/blender/imbuf/intern/png.c @@ -257,6 +257,10 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags) } + if(ibuf->ppm[0] > 0.0 && ibuf->ppm[1] > 0.0) { + png_set_pHYs(png_ptr, info_ptr, (unsigned int)(ibuf->ppm[0] + 0.5), (unsigned int)(ibuf->ppm[1] + 0.5), PNG_RESOLUTION_METER); + } + // write the file header information png_write_info(png_ptr, info_ptr); @@ -384,7 +388,19 @@ struct ImBuf *imb_loadpng(unsigned char *mem, size_t size, int flags) if (ibuf) { ibuf->ftype = PNG; ibuf->profile = IB_PROFILE_SRGB; - } else { + + if (png_get_valid (png_ptr, info_ptr, PNG_INFO_pHYs)) { + int unit_type; + unsigned int xres, yres; + + if(png_get_pHYs(png_ptr, info_ptr, &xres, &yres, &unit_type)) + if(unit_type == PNG_RESOLUTION_METER) { + ibuf->ppm[0]= xres; + ibuf->ppm[1]= yres; + } + } + } + else { printf("Couldn't allocate memory for PNG image\n"); } diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c index 67d20d56466..36130aa0dbf 100644 --- a/source/blender/imbuf/intern/tiff.c +++ b/source/blender/imbuf/intern/tiff.c @@ -354,6 +354,25 @@ static void scanline_separate_32bit(float *rectf, float *fbuf, int scanline_w, i rectf[i*4 + chan] = fbuf[i]; } +static void imb_read_tiff_resolution(ImBuf *ibuf, TIFF *image) +{ + uint16 unit; + float xres; + float yres; + + TIFFGetFieldDefaulted(image, TIFFTAG_RESOLUTIONUNIT, &unit); + TIFFGetFieldDefaulted(image, TIFFTAG_XRESOLUTION, &xres); + TIFFGetFieldDefaulted(image, TIFFTAG_YRESOLUTION, &yres); + + if(unit == RESUNIT_CENTIMETER) { + ibuf->ppm[0]= (double)xres * 100.0; + ibuf->ppm[1]= (double)yres * 100.0; + } + else { + ibuf->ppm[0]= (double)xres / 0.0254; + ibuf->ppm[1]= (double)yres / 0.0254; + } +} /* * Use the libTIFF scanline API to read a TIFF image. @@ -369,10 +388,13 @@ static int imb_read_tiff_pixels(ImBuf *ibuf, TIFF *image, int premul) int ib_flag=0, row, chan; float *fbuf=NULL; unsigned short *sbuf=NULL; - + TIFFGetField(image, TIFFTAG_BITSPERSAMPLE, &bitspersample); TIFFGetField(image, TIFFTAG_SAMPLESPERPIXEL, &spp); /* number of 'channels' */ TIFFGetField(image, TIFFTAG_PLANARCONFIG, &config); + + imb_read_tiff_resolution(ibuf, image); + scanline = TIFFScanlineSize(image); if (bitspersample == 32) { @@ -658,6 +680,7 @@ int imb_savetiff(ImBuf *ibuf, const char *name, int flags) unsigned char *from = NULL, *to = NULL; unsigned short *pixels16 = NULL, *to16 = NULL; float *fromf = NULL; + float xres, yres; int x, y, from_i, to_i, i; int extraSampleTypes[1] = { EXTRASAMPLE_ASSOCALPHA }; @@ -783,8 +806,18 @@ int imb_savetiff(ImBuf *ibuf, const char *name, int flags) TIFFSetField(image, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE); TIFFSetField(image, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB); TIFFSetField(image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); - TIFFSetField(image, TIFFTAG_XRESOLUTION, 150.0); - TIFFSetField(image, TIFFTAG_YRESOLUTION, 150.0); + + + if(ibuf->ppm[0] > 0.0 && ibuf->ppm[1] > 0.0) { + xres= (float)(ibuf->ppm[0] * 0.0254); + yres= (float)(ibuf->ppm[1] * 0.0254); + } + else { + xres= yres= 150.0f; + } + + TIFFSetField(image, TIFFTAG_XRESOLUTION, xres); + TIFFSetField(image, TIFFTAG_YRESOLUTION, yres); TIFFSetField(image, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH); if(TIFFWriteEncodedStrip(image, 0, (bitspersample == 16)? (unsigned char*)pixels16: pixels, diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c index 5872542d10a..3db90c2de0e 100644 --- a/source/blender/makesrna/intern/rna_image.c +++ b/source/blender/makesrna/intern/rna_image.c @@ -221,6 +221,39 @@ static void rna_Image_size_get(PointerRNA *ptr,int *values) BKE_image_release_ibuf(im, lock); } +static void rna_Image_resolution_get(PointerRNA *ptr, float *values) +{ + Image *im= (Image*)ptr->data; + ImBuf *ibuf; + void *lock; + + ibuf = BKE_image_acquire_ibuf(im, NULL , &lock); + if (ibuf) { + values[0]= ibuf->ppm[0]; + values[1]= ibuf->ppm[1]; + } + else { + values[0]= 0; + values[1]= 0; + } + + BKE_image_release_ibuf(im, lock); +} + +static void rna_Image_resolution_set(PointerRNA *ptr, const float *values) +{ + Image *im= (Image*)ptr->data; + ImBuf *ibuf; + void *lock; + + ibuf = BKE_image_acquire_ibuf(im, NULL , &lock); + if (ibuf) { + ibuf->ppm[0]= values[0]; + ibuf->ppm[1]= values[1]; + } + + BKE_image_release_ibuf(im, lock); +} static int rna_Image_depth_get(PointerRNA *ptr) { @@ -557,6 +590,9 @@ static void rna_def_image(BlenderRNA *brna) RNA_def_property_int_funcs(prop, "rna_Image_size_get" , NULL, NULL); RNA_def_property_clear_flag(prop, PROP_EDITABLE); + prop= RNA_def_float_vector(srna, "resolution" , 2 , NULL , 0, 0, "Resolution" , "X/Y pixels per meter" , 0 , 0); + RNA_def_property_float_funcs(prop, "rna_Image_resolution_get" , "rna_Image_resolution_set", NULL); + prop= RNA_def_property(srna, "pixels", PROP_FLOAT, PROP_NONE); RNA_def_property_flag(prop, PROP_DYNAMIC); RNA_def_property_multi_array(prop, 1, NULL); |