static int cpStrips(TIFF* in, TIFF* out) { tsize_t bufsize = TIFFStripSize(in); unsigned char *buf = (unsigned char *)_TIFFmalloc(bufsize); if (buf) { tstrip_t s, ns = TIFFNumberOfStrips(in); uint32 *bytecounts; if (!TIFFGetField(in, TIFFTAG_STRIPBYTECOUNTS, &bytecounts)) { fprintf(stderr, "tiffsplit: strip byte counts are missing\n"); return (0); } for (s = 0; s < ns; s++) { if (bytecounts[s] > (uint32)bufsize) { buf = (unsigned char *)_TIFFrealloc(buf, bytecounts[s]); if (!buf) return (0); bufsize = bytecounts[s]; } if (TIFFReadRawStrip(in, s, buf, bytecounts[s]) < 0 || TIFFWriteRawStrip(out, s, buf, bytecounts[s]) < 0) { _TIFFfree(buf); return (0); } } _TIFFfree(buf); return (1); } return (0); }
static int cpStrips(TIFF* in, TIFF* out) { tsize_t bufsize = TIFFStripSize(in); unsigned char *buf = (unsigned char *)_TIFFmalloc(bufsize); if (buf) { tstrip_t s, ns = TIFFNumberOfStrips(in); tsize_t *bytecounts; TIFFGetField(in, TIFFTAG_STRIPBYTECOUNTS, &bytecounts); for (s = 0; s < ns; s++) { if (bytecounts[s] > bufsize) { buf = (unsigned char *)_TIFFrealloc(buf, bytecounts[s]); if (!buf) goto bad; bufsize = bytecounts[s]; } if (TIFFReadRawStrip(in, s, buf, bytecounts[s]) < 0 || TIFFWriteRawStrip(out, s, buf, bytecounts[s]) < 0) { _TIFFfree(buf); return 0; } } _TIFFfree(buf); return 1; } bad: TIFFError(TIFFFileName(in), "Can't allocate space for strip buffer."); return 0; }
static int cpStrips(TIFF* in, TIFF* out) { tmsize_t bufsize = TIFFStripSize(in); unsigned char *buf = (unsigned char *)_TIFFmalloc(bufsize); if (buf) { tstrip_t s, ns = TIFFNumberOfStrips(in); uint64 *bytecounts; TIFFGetField(in, TIFFTAG_STRIPBYTECOUNTS, &bytecounts); for (s = 0; s < ns; s++) { if (bytecounts[s] > (uint64)bufsize) { buf = (unsigned char *)_TIFFrealloc(buf, (tmsize_t)bytecounts[s]); if (!buf) return (0); bufsize = (tmsize_t)bytecounts[s]; } if (TIFFReadRawStrip(in, s, buf, (tmsize_t)bytecounts[s]) < 0 || TIFFWriteRawStrip(out, s, buf, (tmsize_t)bytecounts[s]) < 0) { _TIFFfree(buf); return (0); } } _TIFFfree(buf); return (1); } return (0); }
static int write_tiff_t85_image(t4_rx_state_t *s) { uint8_t *buf; uint8_t *buf2; int buf_len; int len; int image_len; t85_encode_state_t t85; packer_t packer; /* We need to perform this compression here, as libtiff does not understand it. */ packer.buf = s->tiff.image_buffer; packer.ptr = 0; if (t85_encode_init(&t85, s->metadata.image_width, s->metadata.image_length, row_read_handler, &packer) == NULL) return -1; //if (t->compression == T4_COMPRESSION_T85_L0) // t85_encode_set_options(&t85, 256, -1, -1); buf = NULL; buf_len = 0; image_len = 0; do { if (buf_len < image_len + 65536) { buf_len += 65536; if ((buf2 = span_realloc(buf, buf_len)) == NULL) { if (buf) span_free(buf); return -1; } buf = buf2; } len = t85_encode_get(&t85, &buf[image_len], buf_len - image_len); image_len += len; } while (len > 0); if (TIFFWriteRawStrip(s->tiff.tiff_file, 0, buf, image_len) < 0) { span_log(&s->logging, SPAN_LOG_WARNING, "%s: Error writing TIFF strip.\n", s->tiff.file); return -1; } t85_encode_release(&t85); span_free(buf); return 0; }
static int write_tiff_t43_image(t4_rx_state_t *s) { uint8_t *buf; uint8_t *buf2; int buf_len; int len; int image_len; t43_encode_state_t t43; packer_t packer; packer.buf = s->tiff.image_buffer; packer.ptr = 0; if (t43_encode_init(&t43, s->metadata.image_width, s->metadata.image_length, row_read_handler, &packer) == NULL) return -1; buf = NULL; buf_len = 0; image_len = 0; do { if (buf_len < image_len + 65536) { buf_len += 65536; if ((buf2 = span_realloc(buf, buf_len)) == NULL) { if (buf) span_free(buf); return -1; } buf = buf2; } len = t43_encode_get(&t43, &buf[image_len], buf_len - image_len); image_len += len; } while (len > 0); if (TIFFWriteRawStrip(s->tiff.tiff_file, 0, buf, image_len) < 0) span_log(&s->logging, SPAN_LOG_WARNING, "%s: Error writing TIFF strip.\n", s->tiff.file); t43_encode_release(&t43); span_free(buf); return 0; }
int NITFUncompressBILEVEL( NITFImage *psImage, GByte *pabyInputData, int nInputBytes, GByte *pabyOutputImage ) { int nOutputBytes= (psImage->nBlockWidth * psImage->nBlockHeight + 7)/8; /* -------------------------------------------------------------------- */ /* Write memory TIFF with the bilevel data. */ /* -------------------------------------------------------------------- */ CPLString osFilename; osFilename.Printf( "/vsimem/nitf-wrk-%ld.tif", (long) CPLGetPID() ); VSILFILE* fpL = VSIFOpenL(osFilename, "w+"); if( fpL == NULL ) return FALSE; TIFF *hTIFF = VSI_TIFFOpen( osFilename, "w+", fpL ); if (hTIFF == NULL) { VSIFCloseL(fpL); return FALSE; } TIFFSetField( hTIFF, TIFFTAG_IMAGEWIDTH, psImage->nBlockWidth ); TIFFSetField( hTIFF, TIFFTAG_IMAGELENGTH, psImage->nBlockHeight ); TIFFSetField( hTIFF, TIFFTAG_BITSPERSAMPLE, 1 ); TIFFSetField( hTIFF, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT ); TIFFSetField( hTIFF, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG ); TIFFSetField( hTIFF, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB ); TIFFSetField( hTIFF, TIFFTAG_ROWSPERSTRIP, psImage->nBlockHeight ); TIFFSetField( hTIFF, TIFFTAG_SAMPLESPERPIXEL, 1 ); TIFFSetField( hTIFF, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK ); TIFFSetField( hTIFF, TIFFTAG_COMPRESSION, COMPRESSION_CCITTFAX3 ); if( psImage->szCOMRAT[0] == '2' ) TIFFSetField( hTIFF, TIFFTAG_GROUP3OPTIONS, GROUP3OPT_2DENCODING ); TIFFWriteRawStrip( hTIFF, 0, pabyInputData, nInputBytes ); TIFFWriteDirectory( hTIFF ); TIFFClose( hTIFF ); /* -------------------------------------------------------------------- */ /* Now open and read it back. */ /* -------------------------------------------------------------------- */ int bResult = TRUE; hTIFF = VSI_TIFFOpen( osFilename, "r", fpL ); if (hTIFF == NULL) { VSIFCloseL(fpL); return FALSE; } if( TIFFReadEncodedStrip( hTIFF, 0, pabyOutputImage, nOutputBytes ) == -1 ) { memset( pabyOutputImage, 0, nOutputBytes ); bResult = FALSE; } TIFFClose( hTIFF ); VSIFCloseL(fpL); VSIUnlink( osFilename ); return bResult; }
static int write_tiff_image(t4_rx_state_t *s) { t4_rx_tiff_state_t *t; #if defined(SPANDSP_SUPPORT_TIFF_FX) && TIFFLIB_VERSION >= 20120922 && defined(HAVE_TIF_DIR_H) toff_t diroff; #endif t = &s->tiff; if (s->decoder.no_decoder.buf_ptr <= 0 && (t->image_buffer == NULL || t->image_size <= 0)) return -1; /* Set up the TIFF directory info... */ set_tiff_directory_info(s); /* ...Put the directory in the file before the image data, to get them in the order specified for TIFF/F files... */ //if (!TIFFCheckpointDirectory(t->tiff_file)) // span_log(&s->logging, SPAN_LOG_WARNING, "%s: Failed to checkpoint directory for page %d.\n", t->file, s->current_page); /* ...and write out the image... */ if (s->current_decoder == 0) { if (TIFFWriteRawStrip(s->tiff.tiff_file, 0, s->decoder.no_decoder.buf, s->decoder.no_decoder.buf_ptr) < 0) span_log(&s->logging, SPAN_LOG_WARNING, "%s: Error writing TIFF strip.\n", s->tiff.file); } else { switch (t->compression) { case T4_COMPRESSION_T85: case T4_COMPRESSION_T85_L0: /* We need to perform this compression here, as libtiff does not understand it. */ if (write_tiff_t85_image(s) < 0) return -1; break; #if defined(SPANDSP_SUPPORT_T88) case T4_COMPRESSION_T88: /* We need to perform this compression here, as libtiff does not understand it. */ if (write_tiff_t88_image(s) < 0) return -1; break; #endif case T4_COMPRESSION_T43: /* We need to perform this compression here, as libtiff does not understand it. */ if (write_tiff_t43_image(s) < 0) return -1; break; #if defined(SPANDSP_SUPPORT_T45) case T4_COMPRESSION_T45: /* We need to perform this compression here, as libtiff does not understand it. */ if (write_tiff_t45_image(s) < 0) return -1; break; #endif default: /* Let libtiff do the compression */ if (TIFFWriteEncodedStrip(t->tiff_file, 0, t->image_buffer, t->image_size) < 0) span_log(&s->logging, SPAN_LOG_WARNING, "%s: Error writing TIFF strip.\n", t->file); break; } } /* ...then finalise the directory entry, and libtiff is happy. */ if (!TIFFWriteDirectory(t->tiff_file)) span_log(&s->logging, SPAN_LOG_WARNING, "%s: Failed to write directory for page %d.\n", t->file, s->current_page); #if defined(SPANDSP_SUPPORT_TIFF_FX) /* According to the TIFF/FX spec, a global parameters IFD should only be inserted into the first page in the file */ if (s->current_page == 0) { #if TIFFLIB_VERSION >= 20120922 && defined(HAVE_TIF_DIR_H) if (!TIFFCreateCustomDirectory(t->tiff_file, &tiff_fx_field_array)) { TIFFSetField(t->tiff_file, TIFFTAG_FAXPROFILE, PROFILETYPE_G3_FAX); TIFFSetField(t->tiff_file, TIFFTAG_PROFILETYPE, FAXPROFILE_F); TIFFSetField(t->tiff_file, TIFFTAG_CODINGMETHODS, CODINGMETHODS_T4_1D | CODINGMETHODS_T4_2D | CODINGMETHODS_T6); TIFFSetField(t->tiff_file, TIFFTAG_VERSIONYEAR, "1998"); TIFFSetField(t->tiff_file, TIFFTAG_MODENUMBER, 3); diroff = 0; if (!TIFFWriteCustomDirectory(t->tiff_file, &diroff)) span_log(&s->logging, SPAN_LOG_WARNING, "Failed to write custom directory.\n"); /* Now go back and patch in the pointer to the new IFD */ if (!TIFFSetDirectory(t->tiff_file, s->current_page)) span_log(&s->logging, SPAN_LOG_WARNING, "Failed to set directory.\n"); if (!TIFFSetField(t->tiff_file, TIFFTAG_GLOBALPARAMETERSIFD, diroff)) span_log(&s->logging, SPAN_LOG_WARNING, "Failed to set field.\n"); if (!TIFFWriteDirectory(t->tiff_file)) span_log(&s->logging, SPAN_LOG_WARNING, "%s: Failed to write directory for page %d.\n", t->file, s->current_page); } #endif } #endif return 0; }
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; }