static GpStatus gdip_load_png_properties (png_structp png_ptr, png_infop info_ptr, png_infop end_ptr, BitmapData *bitmap_data) { #if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED) bitmap_data->image_flags |= ImageFlagsHasRealDPI; bitmap_data->dpi_horz = png_get_x_pixels_per_inch(png_ptr, info_ptr); bitmap_data->dpi_vert = png_get_y_pixels_per_inch(png_ptr, info_ptr); #elif defined(PNG_pHYs_SUPPORTED) if ((info_ptr->valid & PNG_INFO_pHYs) && (info_ptr->phys_unit_type == PNG_RESOLUTION_METER)) { bitmap_data->image_flags |= ImageFlagsHasRealDPI; bitmap_data->dpi_horz = info_ptr->x_pixels_per_unit * 0.0254; bitmap_data->dpi_vert = info_ptr->y_pixels_per_unit * 0.0254; } #endif /* default to screen resolution (if nothing was provided or available) */ if (bitmap_data->dpi_horz == 0 || bitmap_data->dpi_vert == 0) { bitmap_data->dpi_horz = bitmap_data->dpi_vert = gdip_get_display_dpi (); } #if defined(PNG_iCCP_SUPPORTED) { png_charp name; png_charp profile; png_uint_32 proflen; int compression_type; if (png_get_iCCP(png_ptr, info_ptr, &name, &compression_type, &profile, &proflen)) { gdip_bitmapdata_property_add_ASCII(bitmap_data, PropertyTagICCProfileDescriptor, (BYTE*)name); gdip_bitmapdata_property_add_byte(bitmap_data, PropertyTagICCProfile, (BYTE)compression_type); } } #endif #if defined(PNG_gAMA_SUPPORTED) { double gamma; if (png_get_gAMA(png_ptr, info_ptr, &gamma)) { gdip_bitmapdata_property_add_rational(bitmap_data, PropertyTagGamma, 100000, gamma * 100000); } } #endif #if defined(PNG_cHRM_SUPPORTED) { double white_x; double white_y; double red_x; double red_y; double green_x; double green_y; double blue_x; double blue_y; if (png_get_cHRM(png_ptr, info_ptr, &white_x, &white_y, &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y)) { BYTE *buffer; guint32 *ptr; buffer = GdipAlloc(6 * (sizeof(png_uint_32) + sizeof(png_uint_32))); if (buffer != NULL) { ptr = (guint32 *)buffer; ptr[0] = (guint32)(red_x * 100000); ptr[1] = 1000000; ptr[2] = (guint32)(red_y * 100000); ptr[3] = 100000; ptr[4] = (guint32)(green_x * 100000); ptr[5] = 1000000; ptr[6] = (guint32)(green_y * 100000); ptr[7] = 100000; ptr[8] = (guint32)(blue_x * 100000); ptr[9] = 100000; ptr[10] = (guint32)(blue_y * 100000); ptr[11] = 100000; gdip_bitmapdata_property_add (bitmap_data, PropertyTagPrimaryChromaticities, 6 * (sizeof(guint32) + sizeof(guint32)), PropertyTagTypeRational, buffer); ptr[0] = (guint32)(white_x * 100000); ptr[1] = 1000000; ptr[2] = (guint32)(white_y * 100000); ptr[3] = 100000; gdip_bitmapdata_property_add (bitmap_data, PropertyTagWhitePoint, 2 * (sizeof(guint32) + sizeof(guint32)), PropertyTagTypeRational, buffer); GdipFree(buffer); } } } #endif #if defined(PNG_pHYs_SUPPORTED) { int unit_type; png_uint_32 res_x; png_uint_32 res_y; if (png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y, &unit_type)) { gdip_bitmapdata_property_add_byte(bitmap_data, PropertyTagPixelUnit, (BYTE)unit_type); gdip_bitmapdata_property_add_long(bitmap_data, PropertyTagPixelPerUnitX, res_x); gdip_bitmapdata_property_add_long(bitmap_data, PropertyTagPixelPerUnitY, res_y); } } #endif #if defined(PNG_TEXT_SUPPORTED) { int num_text; png_textp text_ptr; if (png_get_text(png_ptr, info_ptr, &text_ptr, &num_text)) { if (num_text > 0) { gdip_bitmapdata_property_add_ASCII(bitmap_data, PropertyTagExifUserComment, (BYTE*)text_ptr[0].text); } } } #endif return Ok; }
static GpStatus gdip_load_tiff_properties (TIFF *tiff, BitmapData *bitmap_data) { BYTE *text; uint32 i; uint16 s; uint16 s2; char c; double d; float f; uint16 samples_per_pixel; uint16 bits_per_sample; uint16 planar_configuration; uint32 image_length; uint16 strips_per_image; uint32 rows_per_strip; uint32 tile_length; uint32 tile_width; uint16 compression = 0; samples_per_pixel = 0; bits_per_sample = 0; planar_configuration = 0; image_length = 0; strips_per_image = 0; rows_per_strip = 0; tile_length = 0; tile_width = 0; i = 0; s = 0; s2 = 0; if (TIFFGetField(tiff, TIFFTAG_ARTIST, &text)) { gdip_bitmapdata_property_add_ASCII(bitmap_data, PropertyTagArtist, text); } if (TIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bits_per_sample)) { gdip_bitmapdata_property_add_short(bitmap_data, PropertyTagBitsPerSample, bits_per_sample); } { uint16 *rmap; uint16 *gmap; uint16 *bmap; if (TIFFGetField(tiff, TIFFTAG_COLORMAP, &rmap, &gmap, &bmap)) { BYTE *buffer; uint16 *ptr; if ((rmap != NULL) && (gmap != NULL) && (bmap != NULL)) { buffer = GdipAlloc (3 * bits_per_sample * sizeof (uint16)); if (buffer != NULL) { ptr = (uint16 *)buffer; for (i = 0; i < bits_per_sample; i++) { ptr[0] = rmap[i]; ptr[1] = gmap[i]; ptr[2] = bmap[i]; ptr += 3; } gdip_bitmapdata_property_add(bitmap_data, PropertyTagColorMap, 3 * bits_per_sample * sizeof(uint16), PropertyTagTypeShort, buffer); GdipFree(buffer); } } } } if (TIFFGetField(tiff, TIFFTAG_COMPRESSION, &s)) { compression = s; gdip_bitmapdata_property_add_short(bitmap_data, PropertyTagCompression, s); } if (TIFFGetField(tiff, TIFFTAG_COPYRIGHT, &text)) { gdip_bitmapdata_property_add_ASCII(bitmap_data, PropertyTagCopyright, text); } if (TIFFGetField(tiff, TIFFTAG_DATETIME, &text)) { gdip_bitmapdata_property_add_ASCII(bitmap_data, PropertyTagDateTime, text); } if (TIFFGetField(tiff, TIFFTAG_DOCUMENTNAME, &text)) { gdip_bitmapdata_property_add_ASCII(bitmap_data, PropertyTagDocumentName, text); } if (TIFFGetField(tiff, TIFFTAG_DOTRANGE, &s, &s2)) { gdip_bitmapdata_property_add_srational(bitmap_data, PropertyTagDotRange, s, s2); } { uint16 count; uint16 *samples; if (TIFFGetField(tiff, TIFFTAG_EXTRASAMPLES, &count, &samples)) { if ((count > 0) && (samples != NULL)) { gdip_bitmapdata_property_add(bitmap_data, PropertyTagExtraSamples, count * sizeof(uint16), PropertyTagTypeShort, samples); } } } if (TIFFGetField(tiff, TIFFTAG_FILLORDER, &s)) { gdip_bitmapdata_property_add_short(bitmap_data, PropertyTagFillOrder, s); } if (TIFFGetField(tiff, TIFFTAG_GROUP3OPTIONS, &i, &i)) { gdip_bitmapdata_property_add_long(bitmap_data, PropertyTagT4Option, i); } if (TIFFGetField(tiff, TIFFTAG_GROUP4OPTIONS, &i)) { gdip_bitmapdata_property_add_long(bitmap_data, PropertyTagT6Option, i); } if (TIFFGetField(tiff, TIFFTAG_HALFTONEHINTS, &s, &s2)) { gdip_bitmapdata_property_add_srational(bitmap_data, PropertyTagHalftoneHints, s, s2); } if (TIFFGetField(tiff, TIFFTAG_HOSTCOMPUTER, &text)) { gdip_bitmapdata_property_add_ASCII(bitmap_data, PropertyTagHostComputer, text); } if (TIFFGetField(tiff, TIFFTAG_IMAGEDESCRIPTION, &text)) { gdip_bitmapdata_property_add_ASCII(bitmap_data, PropertyTagImageDescription, text); } if (TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &i)) { gdip_bitmapdata_property_add_long(bitmap_data, PropertyTagImageWidth, i); } if (TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &image_length)) { gdip_bitmapdata_property_add_long(bitmap_data, PropertyTagImageHeight, image_length); } if (TIFFGetField(tiff, TIFFTAG_INKNAMES, &text)) { gdip_bitmapdata_property_add_ASCII(bitmap_data, PropertyTagInkNames, text); } if (TIFFGetField(tiff, TIFFTAG_INKSET, &s)) { gdip_bitmapdata_property_add_short(bitmap_data, PropertyTagInkSet, s); } #ifdef NotImplemented /* Don't know how this property should be stored, datatype is void */ { uint32 count; void *tables; if (TIFFGetField(tiff, TIFFTAG_JPEGTABLES, &count, &tables)) { gdip_bitmapdata_property_add(bitmap_data, PropertyTagJPEGTables, text); } } #endif if (TIFFGetField(tiff, TIFFTAG_JPEGQUALITY, &i)) { gdip_bitmapdata_property_add_long(bitmap_data, PropertyTagJPEGQuality, i); } if (TIFFGetField(tiff, TIFFTAG_MAKE, &text)) { gdip_bitmapdata_property_add_ASCII(bitmap_data, PropertyTagEquipMake, text); } if (TIFFGetField(tiff, TIFFTAG_MAXSAMPLEVALUE, &s)) { gdip_bitmapdata_property_add_short(bitmap_data, PropertyTagMaxSampleValue, s); } if (TIFFGetField(tiff, TIFFTAG_MINSAMPLEVALUE, &s)) { gdip_bitmapdata_property_add_short(bitmap_data, PropertyTagMinSampleValue, s); } if (TIFFGetField(tiff, TIFFTAG_MODEL, &text)) { gdip_bitmapdata_property_add_ASCII(bitmap_data, PropertyTagEquipModel, text); } if (TIFFGetField(tiff, TIFFTAG_ORIENTATION, &s)) { gdip_bitmapdata_property_add_short(bitmap_data, PropertyTagOrientation, s); } if (TIFFGetField(tiff, TIFFTAG_PAGENAME, &text)) { gdip_bitmapdata_property_add_ASCII(bitmap_data, PropertyTagPageName, text); } if (TIFFGetField(tiff, TIFFTAG_PAGENUMBER, &s, &s2)) { gdip_bitmapdata_property_add_short(bitmap_data, PropertyTagPageNumber, s); } if (TIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &s)) { gdip_bitmapdata_property_add_short(bitmap_data, PropertyTagPhotometricInterp, s); } if (TIFFGetField(tiff, TIFFTAG_PLANARCONFIG, &planar_configuration)) { gdip_bitmapdata_property_add_short(bitmap_data, PropertyTagPlanarConfig, planar_configuration); } if (compression == COMPRESSION_ADOBE_DEFLATE) { if (TIFFGetField(tiff, TIFFTAG_PREDICTOR, &s)) { gdip_bitmapdata_property_add_short(bitmap_data, PropertyTagPredictor, s); } } { float *chromacities = NULL; /* 6-entry array */ if (TIFFGetField(tiff, TIFFTAG_PRIMARYCHROMATICITIES, &chromacities) && (chromacities != NULL)) { BYTE *buffer; uint32 *ptr; buffer = GdipAlloc(6 * (sizeof(uint32) + sizeof(uint32))); if (buffer != NULL) { ptr = (uint32 *)buffer; for (i = 0; i < 6; i++) { ptr[0] = (uint32)(chromacities[i] * 1000000); ptr[1] = 1000000; ptr += 2; } gdip_bitmapdata_property_add (bitmap_data, PropertyTagPrimaryChromaticities, 6 * (sizeof(uint32) + sizeof(uint32)), PropertyTagTypeRational, buffer); GdipFree(buffer); } } } if (TIFFGetField(tiff, TIFFTAG_RESOLUTIONUNIT, &s)) { gdip_bitmapdata_property_add_short(bitmap_data, PropertyTagResolutionUnit, s); } if (TIFFGetField(tiff, TIFFTAG_ROWSPERSTRIP, &rows_per_strip)) { gdip_bitmapdata_property_add_long(bitmap_data, PropertyTagRowsPerStrip, rows_per_strip); } if (TIFFGetField(tiff, TIFFTAG_SAMPLEFORMAT, &s)) { gdip_bitmapdata_property_add_short(bitmap_data, PropertyTagSampleFormat, s); } if (TIFFGetField(tiff, TIFFTAG_SAMPLESPERPIXEL, &samples_per_pixel)) { gdip_bitmapdata_property_add_short(bitmap_data, PropertyTagSamplesPerPixel, samples_per_pixel); } if (samples_per_pixel > 0) { float *ref_blackwhite; /* 2 * SamplesPerPixel array */ if (TIFFGetField(tiff, TIFFTAG_REFERENCEBLACKWHITE, &ref_blackwhite)) { BYTE *buffer; uint32 *ptr; buffer = GdipAlloc(2 * samples_per_pixel * (sizeof(uint32) + sizeof(uint32))); if (buffer != NULL) { ptr = (uint32 *)buffer; for (i = 0; i < 2 * samples_per_pixel; i++) { ptr[0] = (uint32)(ref_blackwhite[i] * 1000000); ptr[1] = 1000000; ptr += 2; } gdip_bitmapdata_property_add (bitmap_data, PropertyTagREFBlackWhite, 6 * (sizeof(uint32) + sizeof(uint32)), PropertyTagTypeRational, buffer); GdipFree(buffer); } } } if (TIFFGetField(tiff, TIFFTAG_SMAXSAMPLEVALUE, &d)) { gdip_bitmapdata_property_add_rational(bitmap_data, PropertyTagSMaxSampleValue, d * 1000000, 1000000); } if (TIFFGetField(tiff, TIFFTAG_SMINSAMPLEVALUE, &d)) { gdip_bitmapdata_property_add_rational(bitmap_data, PropertyTagSMinSampleValue, d * 1000000, 1000000); } if (TIFFGetField(tiff, TIFFTAG_SOFTWARE, &text)) { gdip_bitmapdata_property_add_ASCII(bitmap_data, PropertyTagSoftwareUsed, text); } if ((rows_per_strip != 0) && (planar_configuration != 0)) { uint32 *bytecounts; uint32 *offsets; int count; strips_per_image = floor ((image_length + rows_per_strip - 1) / rows_per_strip); if (planar_configuration == 1) { count = strips_per_image; } else { count = samples_per_pixel * strips_per_image; } if (TIFFGetField(tiff, TIFFTAG_STRIPBYTECOUNTS, &bytecounts)) { gdip_bitmapdata_property_add(bitmap_data, PropertyTagStripBytesCount, count * sizeof(uint32), PropertyTagTypeLong, bytecounts); } if (TIFFGetField(tiff, TIFFTAG_STRIPOFFSETS, &offsets)) { gdip_bitmapdata_property_add(bitmap_data, PropertyTagStripOffsets, count * sizeof(uint32), PropertyTagTypeLong, offsets); } } if (TIFFGetField(tiff, TIFFTAG_SUBFILETYPE, &i)) { gdip_bitmapdata_property_add_long(bitmap_data, PropertyTagNewSubfileType, i); } if (TIFFGetField(tiff, TIFFTAG_TARGETPRINTER, &text)) { gdip_bitmapdata_property_add_ASCII(bitmap_data, PropertyTagTargetPrinter, text); } if (TIFFGetField(tiff, TIFFTAG_THRESHHOLDING, &s)) { gdip_bitmapdata_property_add_short(bitmap_data, PropertyTagThreshHolding, s); } if (TIFFGetField(tiff, TIFFTAG_TILEWIDTH, &tile_width)) { gdip_bitmapdata_property_add_long(bitmap_data, PropertyTagTileWidth, tile_width); } if (TIFFGetField(tiff, TIFFTAG_TILELENGTH, &tile_length)) { gdip_bitmapdata_property_add_long(bitmap_data, PropertyTagTileLength, tile_length); } if ((planar_configuration != 0) && (tile_width != 0) && (tile_length != 0)) { uint32 *byte_counts; uint32 *offsets; uint32 tiles_across; uint32 tiles_down; int tiles_per_image; int count; tiles_across = (image_length + tile_width - 1) / tile_width; tiles_down = (image_length + tile_length - 1) / tile_length; tiles_per_image = tiles_across * tiles_down; if (planar_configuration == 1) { count = tiles_per_image; } else { count = samples_per_pixel * tiles_per_image; } if (TIFFGetField(tiff, TIFFTAG_TILEBYTECOUNTS, &byte_counts)) { gdip_bitmapdata_property_add(bitmap_data, PropertyTagTileByteCounts, count * sizeof(uint32), PropertyTagTypeLong, byte_counts); } if (TIFFGetField(tiff, TIFFTAG_TILEOFFSETS, &offsets)) { gdip_bitmapdata_property_add(bitmap_data, PropertyTagTileOffset, count * sizeof(uint32), PropertyTagTypeLong, offsets); } } if (samples_per_pixel == 1) { uint16 *sample; if (TIFFGetField(tiff, TIFFTAG_TRANSFERFUNCTION, &sample)) { gdip_bitmapdata_property_add (bitmap_data, PropertyTagTransferFunction, (1 << bits_per_sample) * sizeof(uint16), PropertyTagTypeShort, sample); } } else if (samples_per_pixel == 3) { uint16 *r; uint16 *g; uint16 *b; if (TIFFGetField(tiff, TIFFTAG_TRANSFERFUNCTION, &r, &g, &b)) { BYTE *buffer; uint16 *ptr; buffer = GdipAlloc(3 * (1 << samples_per_pixel) * sizeof(uint16)); if (buffer != NULL) { ptr = (uint16 *)buffer; for (i = 0; i < 1 << bits_per_sample; i++) { ptr[i] = r[i]; ptr[i + 1] = g[i]; ptr[i + 2] = b[i]; } gdip_bitmapdata_property_add (bitmap_data, PropertyTagTransferFunction, 3 * (1 << samples_per_pixel) * sizeof(uint16), PropertyTagTypeShort, buffer); GdipFree(buffer); } } } { float *whitepoints; if (TIFFGetField(tiff, TIFFTAG_WHITEPOINT, &whitepoints)) { BYTE *buffer; uint32 *ptr; buffer = GdipAlloc(2 * (sizeof(uint32) + sizeof(uint32))); if (buffer != NULL) { ptr = (uint32 *)buffer; ptr[0] = whitepoints[0] * 1000000; ptr[1] = 1000000; ptr[2] = whitepoints[1] * 1000000; ptr[3] = 1000000; gdip_bitmapdata_property_add (bitmap_data, PropertyTagTransferFunction, 2 * (sizeof(uint32) + sizeof(uint32)), PropertyTagTypeRational, buffer); GdipFree(buffer); } gdip_bitmapdata_property_add_rational(bitmap_data, PropertyTagWhitePoint, whitepoints[0] * 1000000, 1000000); } } if (TIFFGetField(tiff, TIFFTAG_XPOSITION, &f)) { gdip_bitmapdata_property_add_rational(bitmap_data, PropertyTagXPosition, f * 1000000, 1000000); } if (TIFFGetField(tiff, TIFFTAG_XRESOLUTION, &f)) { gdip_bitmapdata_property_add_rational(bitmap_data, PropertyTagXResolution, f, 1); } { float *coefficients; if (TIFFGetField(tiff, TIFFTAG_YCBCRCOEFFICIENTS, &coefficients)) { BYTE buffer[sizeof(uint32) * 6]; uint32 *ptr; ptr = (uint32 *)&buffer; ptr[0] = (uint32)(coefficients[0] * 1000000); ptr[1] = 1000000; ptr[2] = (uint32)(coefficients[1] * 1000000); ptr[3] = 1000000; ptr[4] = (uint32)(coefficients[2] * 1000000); ptr[5] = 1000000; gdip_bitmapdata_property_add(bitmap_data, PropertyTagYCbCrCoefficients, sizeof(uint32) * 6, PropertyTagTypeRational, buffer); } } if (TIFFGetField(tiff, TIFFTAG_YCBCRPOSITIONING, &s)) { gdip_bitmapdata_property_add_short(bitmap_data, PropertyTagYCbCrPositioning, s); } if (TIFFGetField(tiff, TIFFTAG_YCBCRSUBSAMPLING, &s, &s2)) { gdip_bitmapdata_property_add_srational(bitmap_data, PropertyTagYCbCrSubsampling, s, s2); } if (TIFFGetField(tiff, TIFFTAG_YPOSITION, &f)) { gdip_bitmapdata_property_add_rational(bitmap_data, PropertyTagYPosition, f * 1000000, 1000000); } if (TIFFGetField(tiff, TIFFTAG_YRESOLUTION, &f)) { gdip_bitmapdata_property_add_rational(bitmap_data, PropertyTagYResolution, f, 1); } #ifdef NotImplemented /* Not sure what type the data is */ { uint32 count; void *profile_data; if (TIFFGetField(tiff, TIFFTAG_ICCPROFILE, &count, &profile_data)) { gdip_bitmapdata_property_add(bitmap_data, PropertyTagICCProfile, count * sizeof(void *), , profile_data); } }