static int cpTiles(TIFF* in, TIFF* out) { tsize_t bufsize = TIFFTileSize(in); unsigned char *buf = (unsigned char *)_TIFFmalloc(bufsize); if (buf) { ttile_t t, nt = TIFFNumberOfTiles(in); uint32 *bytecounts; if (!TIFFGetField(in, TIFFTAG_TILEBYTECOUNTS, &bytecounts)) { fprintf(stderr, "tiffsplit: tile byte counts are missing\n"); return (0); } for (t = 0; t < nt; t++) { if (bytecounts[t] > (uint32) bufsize) { buf = (unsigned char *)_TIFFrealloc(buf, bytecounts[t]); if (!buf) return (0); bufsize = bytecounts[t]; } if (TIFFReadRawTile(in, t, buf, bytecounts[t]) < 0 || TIFFWriteRawTile(out, t, buf, bytecounts[t]) < 0) { _TIFFfree(buf); return (0); } } _TIFFfree(buf); return (1); } return (0); }
static int cpTiles(TIFF* in, TIFF* out) { tsize_t bufsize = TIFFTileSize(in); unsigned char *buf = (unsigned char *)_TIFFmalloc(bufsize); if (buf) { ttile_t t, nt = TIFFNumberOfTiles(in); tsize_t *bytecounts; TIFFGetField(in, TIFFTAG_TILEBYTECOUNTS, &bytecounts); for (t = 0; t < nt; t++) { if (bytecounts[t] > bufsize) { buf = (unsigned char *)_TIFFrealloc(buf, bytecounts[t]); if (!buf) goto bad; bufsize = bytecounts[t]; } if (TIFFReadRawTile(in, t, buf, bytecounts[t]) < 0 || TIFFWriteRawTile(out, t, buf, bytecounts[t]) < 0) { _TIFFfree(buf); return 0; } } _TIFFfree(buf); return 1; } bad: TIFFError(TIFFFileName(in), "Can't allocate space for tile buffer."); return (0); }
static int cpTiles(TIFF* in, TIFF* out) { tmsize_t bufsize = TIFFTileSize(in); unsigned char *buf = (unsigned char *)_TIFFmalloc(bufsize); if (buf) { ttile_t t, nt = TIFFNumberOfTiles(in); uint64 *bytecounts; TIFFGetField(in, TIFFTAG_TILEBYTECOUNTS, &bytecounts); for (t = 0; t < nt; t++) { if (bytecounts[t] > (uint64) bufsize) { buf = (unsigned char *)_TIFFrealloc(buf, (tmsize_t)bytecounts[t]); if (!buf) return (0); bufsize = (tmsize_t)bytecounts[t]; } if (TIFFReadRawTile(in, t, buf, (tmsize_t)bytecounts[t]) < 0 || TIFFWriteRawTile(out, t, buf, (tmsize_t)bytecounts[t]) < 0) { _TIFFfree(buf); return (0); } } _TIFFfree(buf); return (1); } return (0); }
static void aperio_tiff_tilereader(openslide_t *osr, TIFF *tiff, uint32_t *dest, int64_t x, int64_t y, int32_t w, int32_t h) { // which compression? uint16_t compression_mode; TIFFGetField(tiff, TIFFTAG_COMPRESSION, &compression_mode); // not for us? fallback if ((compression_mode != APERIO_COMPRESSION_JP2K_YCBCR) && (compression_mode != APERIO_COMPRESSION_JP2K_RGB)) { _openslide_generic_tiff_tilereader(osr, tiff, dest, x, y, w, h); return; } // else, JPEG 2000! opj_cio_t *stream = NULL; opj_dinfo_t *dinfo = NULL; opj_image_t *image = NULL; opj_image_comp_t *comps = NULL; // note: don't use info_handler, it outputs lots of junk opj_event_mgr_t event_callbacks = { .error_handler = error_callback, .warning_handler = warning_callback, }; // get tile number ttile_t tile_no = TIFFComputeTile(tiff, x, y, 0, 0); // g_debug("aperio reading tile_no: %d", tile_no); // get tile size toff_t *sizes; if (TIFFGetField(tiff, TIFFTAG_TILEBYTECOUNTS, &sizes) == 0) { _openslide_set_error(osr, "Cannot get tile size"); return; // ok, haven't allocated anything yet } tsize_t tile_size = sizes[tile_no]; // a slide with zero-length tiles has been seen in the wild if (!tile_size) { // fill with transparent memset(dest, 0, w * h * 4); //g_debug("skipping tile %d", tile_no); return; // ok, haven't allocated anything yet } // get raw tile tdata_t buf = g_slice_alloc(tile_size); tsize_t size = TIFFReadRawTile(tiff, tile_no, buf, tile_size); if (size == -1) { _openslide_set_error(osr, "Cannot get raw tile"); goto DONE; } // init decompressor opj_dparameters_t parameters; dinfo = opj_create_decompress(CODEC_J2K); opj_set_default_decoder_parameters(¶meters); opj_setup_decoder(dinfo, ¶meters); stream = opj_cio_open((opj_common_ptr) dinfo, buf, size); opj_set_event_mgr((opj_common_ptr) dinfo, &event_callbacks, osr); // decode image = opj_decode(dinfo, stream); // check error if (openslide_get_error(osr)) { goto DONE; } comps = image->comps; // sanity check if (image->numcomps != 3) { _openslide_set_error(osr, "image->numcomps != 3"); goto DONE; } // TODO more checks? copy_aperio_tile(compression_mode, comps, dest, w, h, w / comps[0].w, h / comps[0].h, w / comps[1].w, h / comps[1].h, w / comps[2].w, h / comps[2].h); DONE: // erase g_slice_free1(tile_size, buf); if (image) opj_image_destroy(image); if (stream) opj_cio_close(stream); if (dinfo) opj_destroy_decompress(dinfo); }
int PS_Lvl2page(FILE* fd, TIFF* tif, uint32 w, uint32 h) { uint16 fillorder; int use_rawdata, tiled_image, breaklen; uint32 chunk_no, num_chunks, *bc; unsigned char *buf_data, *cp; tsize_t chunk_size, byte_count; #if defined( EXP_ASCII85ENCODER ) int ascii85_l; /* Length, in bytes, of ascii85_p[] data */ uint8 * ascii85_p = 0; /* Holds ASCII85 encoded data */ #endif PS_Lvl2colorspace(fd, tif); use_rawdata = PS_Lvl2ImageDict(fd, tif, w, h); fputs("%%BeginData:\n", fd); fputs("exec\n", fd); tiled_image = TIFFIsTiled(tif); if (tiled_image) { num_chunks = TIFFNumberOfTiles(tif); TIFFGetField(tif, TIFFTAG_TILEBYTECOUNTS, &bc); } else { num_chunks = TIFFNumberOfStrips(tif); TIFFGetField(tif, TIFFTAG_STRIPBYTECOUNTS, &bc); } if (use_rawdata) { chunk_size = bc[0]; for (chunk_no = 1; chunk_no < num_chunks; chunk_no++) if (bc[chunk_no] > chunk_size) chunk_size = bc[chunk_no]; } else { if (tiled_image) chunk_size = TIFFTileSize(tif); else chunk_size = TIFFStripSize(tif); } buf_data = (unsigned char *)_TIFFmalloc(chunk_size); if (!buf_data) { TIFFError(filename, "Can't alloc %u bytes for %s.", chunk_size, tiled_image ? "tiles" : "strips"); return(FALSE); } #if defined( EXP_ASCII85ENCODER ) if ( ascii85 ) { /* * Allocate a buffer to hold the ASCII85 encoded data. Note * that it is allocated with sufficient room to hold the * encoded data (5*chunk_size/4) plus the EOD marker (+8) * and formatting line breaks. The line breaks are more * than taken care of by using 6*chunk_size/4 rather than * 5*chunk_size/4. */ ascii85_p = _TIFFmalloc( (chunk_size+(chunk_size/2)) + 8 ); if ( !ascii85_p ) { _TIFFfree( buf_data ); TIFFError( filename, "Cannot allocate ASCII85 encoding buffer." ); return ( FALSE ); } } #endif TIFFGetFieldDefaulted(tif, TIFFTAG_FILLORDER, &fillorder); for (chunk_no = 0; chunk_no < num_chunks; chunk_no++) { if (ascii85) Ascii85Init(); else breaklen = 36; if (use_rawdata) { if (tiled_image) byte_count = TIFFReadRawTile(tif, chunk_no, buf_data, chunk_size); else byte_count = TIFFReadRawStrip(tif, chunk_no, buf_data, chunk_size); if (fillorder == FILLORDER_LSB2MSB) TIFFReverseBits(buf_data, byte_count); } else { if (tiled_image) byte_count = TIFFReadEncodedTile(tif, chunk_no, buf_data, chunk_size); else byte_count = TIFFReadEncodedStrip(tif, chunk_no, buf_data, chunk_size); } if (byte_count < 0) { TIFFError(filename, "Can't read %s %d.", tiled_image ? "tile" : "strip", chunk_no); if (ascii85) Ascii85Put('\0', fd); } if (ascii85) { #if defined( EXP_ASCII85ENCODER ) ascii85_l = Ascii85EncodeBlock(ascii85_p, 1, buf_data, byte_count ); if ( ascii85_l > 0 ) fwrite( ascii85_p, ascii85_l, 1, fd ); #else for (cp = buf_data; byte_count > 0; byte_count--) Ascii85Put(*cp++, fd); #endif } else { for (cp = buf_data; byte_count > 0; byte_count--) { putc(hex[((*cp)>>4)&0xf], fd); putc(hex[(*cp)&0xf], fd); cp++; if (--breaklen <= 0) { putc('\n', fd); breaklen = 36; } } } if ( !ascii85 ) { if ( level2 ) putc( '>', fd ); putc('\n', fd); } #if !defined( EXP_ASCII85ENCODER ) else Ascii85Flush(fd); #endif } #if defined( EXP_ASCII85ENCODER ) if ( ascii85_p ) _TIFFfree( ascii85_p ); #endif _TIFFfree(buf_data); fputs("%%EndData\n", fd); return(TRUE); }