KDint xmGetInfoTIFF ( KDFile* file, XMImage* image ) { TIFFInfo* info = 0; image->info = kdCalloc ( 1, sizeof ( TIFFInfo ) ); info = (TIFFInfo*) image->info; if ( !info ) { return -1; } info->tiff = TIFFStreamOpen ( file ); if ( !info->tiff ) { kdSetError ( KD_EILSEQ ); return -1; } image->type = KD_IMAGE_TYPE_TIFF; image->bpp = 32; image->alpha = 8; image->format = KD_IMAGE_FORMAT_RGBA_ATX; image->flip_y = 0; image->bitmask[0] = 0x000000FF; image->bitmask[1] = 0x0000FF00; image->bitmask[2] = 0x00FF0000; TIFFGetField ( info->tiff, TIFFTAG_IMAGEWIDTH , &image->width ); TIFFGetField ( info->tiff, TIFFTAG_IMAGELENGTH , &image->height ); return 0; }
istream_device( std::istream & in ) : _in( in ) { TIFF* tiff; io_error_if( ( tiff = TIFFStreamOpen( "" , &_in ) ) == NULL , "istream_device: failed to stream" ); _tiff_file = tiff_file_t( tiff, TIFFClose ); }
ostream_device( std::ostream & out ) : _out( out ) { TIFF* tiff; io_error_if( ( tiff = TIFFStreamOpen( "" , &_out ) ) == NULL , "ostream_device: failed to stream" ); _tiff_file = tiff_file_t( tiff, TIFFClose ); }
Pixels readPDFImage(PoDoFo::PdfObject* object, const PixelType type, const ColorSpace colorspace, const PoDoFo::pdf_int64 componentbits, const std::string& filename, Form& form) { Pixels pixels; if (!object->GetDictionary().HasKey(PoDoFo::PdfName("Width")) || !object->GetDictionary().HasKey(PoDoFo::PdfName("Height"))) return pixels; const unsigned int width = object->GetDictionary().GetKey(PoDoFo::PdfName("Width"))->GetNumber(); const unsigned int height = object->GetDictionary().GetKey(PoDoFo::PdfName("Height"))->GetNumber(); if (type == PixelType::JPG) { PoDoFo::PdfMemStream* stream = dynamic_cast<PoDoFo::PdfMemStream*>(object->GetStream()); pixels = Pixels(IL_JPG, stream->Get(), stream->GetLength(), filename); } else if (type == PixelType::TIF) { // Monochrome, otherwise wouldn't have used CCITT const unsigned int bits = 1; const unsigned int samples = 1; if (bits != componentbits) form.log("BitsPerComponent is not 1 for CCITTFaxDecode image in PDF", LogType::Warning); std::ostringstream os; TIFF* tif = TIFFStreamOpen("Input", &os); TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width); TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height); TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bits); TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, samples); TIFFSetField(tif, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB); TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE); TIFFSetField(tif, TIFFTAG_XRESOLUTION, 204.0); // From fax2tiff TIFFSetField(tif, TIFFTAG_YRESOLUTION, 196.0); // ditto TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH); TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_CCITTFAX4); TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_CLASSF); TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, (uint32)-1L); // stream->Get returns read-only, so copy it PoDoFo::PdfMemStream* stream = dynamic_cast<PoDoFo::PdfMemStream*>(object->GetStream()); const char* readonly = stream->Get(); PoDoFo::pdf_long len = stream->GetLength(); char* buffer = new char[len]; std::memcpy(buffer, readonly, len); TIFFWriteRawStrip(tif, 0, buffer, len); TIFFWriteDirectory(tif); TIFFClose(tif); delete[] buffer; pixels = Pixels(IL_TIF, os.str().c_str(), os.tellp(), filename); } else { std::ostringstream os; // P4 is bitmap (1 bit), P5 is graymap (8 bit), P6 is pixmap (24 bit or // 8-bit/channel). See: // http://netpbm.sourceforge.net/doc/pbm.html // http://en.wikipedia.org/wiki/Portable_anymap#File_format_description if (colorspace == ColorSpace::Gray) os << ((componentbits == 1)?"P4\n":"P5\n"); else os << "P6\n"; os << width << " " << height << "\n"; if (componentbits != 1) os << "255\n"; std::string s = os.str(); char* buffer; PoDoFo::pdf_long len; object->GetStream()->GetFilteredCopy(&buffer, &len); // Warn if unknown colorspace if (colorspace == ColorSpace::Unknown) form.log("unknown color space on PDF image", LogType::Warning); // If the buffer isn't the correct size for the image data, don't try // reading the image from this invalid data if (len != correctLength(width, height, colorspace, componentbits)) { std::ostringstream ss; ss << "wrong buffer size for PDF image of size " << width << "x" << height << " (" << colorspace << "): " << len; form.log(ss.str(), LogType::Warning); std::free(buffer); return pixels; } std::unique_ptr<char> stream(new char[len+s.size()]); std::memcpy(stream.get(), s.c_str(), s.size()); std::memcpy(stream.get()+s.size(), buffer, len); std::free(buffer); pixels = Pixels(IL_PNM, stream.get(), len+s.size(), filename); } return pixels; }