Ejemplo n.º 1
0
void
TIFFCleanup(TIFF *tif)
{
    if (tif->tif_mode != O_RDONLY)
        /*
         * Flush buffered data and directory (if dirty).
         */
        TIFFFlush(tif);

    (*tif->tif_cleanup)(tif);
    TIFFFreeDirectory(tif);

    if (tif->tif_dirlist)
        _TIFFfree(tif->tif_dirlist);

    /* Clean up client info links */
    while (tif->tif_clientinfo)
    {
        TIFFClientInfoLink *link = tif->tif_clientinfo;

        tif->tif_clientinfo = link->next;
        _TIFFfree(link->name);
        _TIFFfree(link);
    }

    if (tif->tif_rawdata && (tif->tif_flags & TIFF_MYBUFFER))
        _TIFFfree(tif->tif_rawdata);

    if (isMapped(tif))
        TIFFUnmapFileContents(tif, tif->tif_base, tif->tif_size);

    /* Clean up custom fields */
    if (tif->tif_nfields > 0)
    {
        size_t i;

        for (i = 0; i < tif->tif_nfields; i++)
        {
            TIFFFieldInfo *fld = tif->tif_fieldinfo[i];
            if (fld->field_bit == FIELD_CUSTOM &&
                strncmp("Tag ", fld->field_name, 4) == 0)
            {
                _TIFFfree(fld->field_name);
                _TIFFfree(fld);
            }
        }

        _TIFFfree(tif->tif_fieldinfo);
    }

    _TIFFfree(tif);
}
Ejemplo n.º 2
0
void
TIFFClose(TIFF* tif)
{
	if (tif->tif_mode != O_RDONLY)
		/*
		 * Flush buffered data and directory (if dirty).
		 */
		TIFFFlush(tif);
	(*tif->tif_cleanup)(tif);
	TIFFFreeDirectory(tif);
	if (tif->tif_rawdata && (tif->tif_flags&TIFF_MYBUFFER))
		_TIFFfree(tif->tif_rawdata);
	if (isMapped(tif))
		TIFFUnmapFileContents(tif, tif->tif_base, tif->tif_size);
	(void) TIFFCloseFile(tif);
	if (tif->tif_fieldinfo)
		_TIFFfree(tif->tif_fieldinfo);
	_TIFFfree(tif);
}
static void TIFFWriteOvrRow( TIFFOvrCache * psCache )

{
    int		nRet, iTileX, iTileY = psCache->nBlockOffset;
    unsigned char *pabyData;
    uint32	nBaseDirOffset;
    uint32 RowsInStrip;

/* -------------------------------------------------------------------- */
/*      If the output cache is multi-byte per sample, and the file      */
/*      being written to is of a different byte order than the current  */
/*      platform, we will need to byte swap the data.                   */
/* -------------------------------------------------------------------- */
    if( TIFFIsByteSwapped(psCache->hTIFF) )
    {
        if( psCache->nBitsPerPixel == 16 )
            TIFFSwabArrayOfShort( (uint16 *) psCache->pabyRow1Blocks,
                      (psCache->nBytesPerBlock * psCache->nSamples) / 2 );

        else if( psCache->nBitsPerPixel == 32 )
            TIFFSwabArrayOfLong( (uint32 *) psCache->pabyRow1Blocks,
                         (psCache->nBytesPerBlock * psCache->nSamples) / 4 );

        else if( psCache->nBitsPerPixel == 64 )
            TIFFSwabArrayOfDouble( (double *) psCache->pabyRow1Blocks,
                         (psCache->nBytesPerBlock * psCache->nSamples) / 8 );
    }

/* -------------------------------------------------------------------- */
/*      Record original directory position, so we can restore it at     */
/*      end.                                                            */
/* -------------------------------------------------------------------- */
    nBaseDirOffset = TIFFCurrentDirOffset( psCache->hTIFF );
    nRet = TIFFSetSubDirectory( psCache->hTIFF, psCache->nDirOffset );
    assert( nRet == 1 );

/* -------------------------------------------------------------------- */
/*      Write blocks to TIFF file.                                      */
/* -------------------------------------------------------------------- */
	for( iTileX = 0; iTileX < psCache->nBlocksPerRow; iTileX++ )
	{
		int nTileID;

		if (psCache->nPlanarConfig == PLANARCONFIG_SEPARATE)
		{
			int iSample;

			for( iSample = 0; iSample < psCache->nSamples; iSample++ )
			{
				pabyData = TIFFGetOvrBlock( psCache, iTileX, iTileY, iSample );

				if( psCache->bTiled )
				{
					nTileID = TIFFComputeTile( psCache->hTIFF,
					    iTileX * psCache->nBlockXSize,
					    iTileY * psCache->nBlockYSize,
					    0, (tsample_t) iSample );
					TIFFWriteEncodedTile( psCache->hTIFF, nTileID,
					    pabyData,
					    TIFFTileSize(psCache->hTIFF) );
				}
				else
				{
					nTileID = TIFFComputeStrip( psCache->hTIFF,
					    iTileY * psCache->nBlockYSize,
					    (tsample_t) iSample );
					RowsInStrip=psCache->nBlockYSize;
					if ((iTileY+1)*psCache->nBlockYSize>psCache->nYSize)
						RowsInStrip=psCache->nYSize-iTileY*psCache->nBlockYSize;
					TIFFWriteEncodedStrip( psCache->hTIFF, nTileID,
					    pabyData,
					    TIFFVStripSize(psCache->hTIFF,RowsInStrip) );
				}
			}

		}
		else
		{
			pabyData = TIFFGetOvrBlock( psCache, iTileX, iTileY, 0 );

			if( psCache->bTiled )
			{
				nTileID = TIFFComputeTile( psCache->hTIFF,
				    iTileX * psCache->nBlockXSize,
				    iTileY * psCache->nBlockYSize,
				    0, 0 );
				TIFFWriteEncodedTile( psCache->hTIFF, nTileID,
				    pabyData,
				    TIFFTileSize(psCache->hTIFF) );
			}
			else
			{
				nTileID = TIFFComputeStrip( psCache->hTIFF,
				    iTileY * psCache->nBlockYSize,
				    0 );
				RowsInStrip=psCache->nBlockYSize;
				if ((iTileY+1)*psCache->nBlockYSize>psCache->nYSize)
					RowsInStrip=psCache->nYSize-iTileY*psCache->nBlockYSize;
				TIFFWriteEncodedStrip( psCache->hTIFF, nTileID,
				    pabyData,
				    TIFFVStripSize(psCache->hTIFF,RowsInStrip) );
			}
		}
	}
	/* TODO: add checks on error status return of TIFFWriteEncodedTile and TIFFWriteEncodedStrip */

/* -------------------------------------------------------------------- */
/*      Rotate buffers.                                                 */
/* -------------------------------------------------------------------- */
    pabyData = psCache->pabyRow1Blocks;
    psCache->pabyRow1Blocks = psCache->pabyRow2Blocks;
    psCache->pabyRow2Blocks = pabyData;

    _TIFFmemset( pabyData, 0, psCache->nBytesPerRow );

    psCache->nBlockOffset++;

/* -------------------------------------------------------------------- */
/*      Restore access to original directory.                           */
/* -------------------------------------------------------------------- */
    TIFFFlush( psCache->hTIFF );
    /* TODO: add checks on error status return of TIFFFlush */
    TIFFSetSubDirectory( psCache->hTIFF, nBaseDirOffset );
    /* TODO: add checks on error status return of TIFFSetSubDirectory */
}
Ejemplo n.º 4
0
void TIFFFormat::do_write(image_list* input, byte_sink* output, const options_map& opts, bool is_multi) {
    tiff_warn_error twe;
    tsize_t (*read_function)(thandle_t, void*, tsize_t) =
         (dynamic_cast<byte_source*>(output) ?
                            tiff_read_from_writer :
                            tiff_no_read);
    tif_holder t = TIFFClientOpen(
                    "internal",
                    "w",
                    output,
                    read_function,
                    tiff_write,
                    tiff_seek<byte_sink>,
                    tiff_close,
                    tiff_size<byte_sink>,
                    NULL,
                    NULL);
    std::vector<uint8_t> bufdata;
    const unsigned n_pages = input->size();
    for (unsigned i = 0; i != n_pages; ++i) {
        Image* im = input->at(i);
        void* bufp = 0;
        bool copy_data = false;
        const uint32 h = im->dim(0);
        const uint16 photometric = ((im->ndims() == 3 && im->dim(2)) ?
                                                        PHOTOMETRIC_RGB :
                                                        PHOTOMETRIC_MINISBLACK);
        TIFFSetField(t.tif, TIFFTAG_IMAGELENGTH, uint32(h));
        TIFFSetField(t.tif, TIFFTAG_IMAGEWIDTH, uint32(im->dim(1)));
        TIFFSetField(t.tif, TIFFTAG_BITSPERSAMPLE, uint16(im->nbits()));
        TIFFSetField(t.tif, TIFFTAG_SAMPLESPERPIXEL, uint16(im->dim_or(2, 1)));
        TIFFSetField(t.tif, TIFFTAG_PHOTOMETRIC, uint16(photometric));
        TIFFSetField(t.tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);

        if (get_optional_bool(opts, "tiff:compress", true)) {
            TIFFSetField(t.tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
            // For 8 bit images, prediction defaults to false; for 16 bit images,
            // it defaults to true. This is because compression of raw 16 bit
            // images is often counter-productive without this flag. See the
            // discusssion at http://www.asmail.be/msg0055176395.html
            const bool prediction_default = im->nbits() != 8;
            if (get_optional_bool(opts, "tiff:horizontal-predictor", prediction_default)) {
                TIFFSetField(t.tif, TIFFTAG_PREDICTOR, PREDICTOR_HORIZONTAL);
                if (!copy_data) {
                    bufdata.resize(im->dim(1) * im->nbytes());
                    bufp = &bufdata[0];
                    copy_data = true;
                }
            }
        }

        TIFFSetField(t.tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
        const char* meta = get_optional_cstring(opts, "metadata");
        if (meta) {
            TIFFSetField(t.tif, TIFFTAG_IMAGEDESCRIPTION, meta);
        }
        options_map::const_iterator x_iter = opts.find("tiff:XResolution");
        if (x_iter != opts.end()) {
            double d;
            int i;
            float value;
            if (x_iter->second.get_int(i)) { value = i; }
            else if (x_iter->second.get_double(d)) { value = d; }
            else { throw WriteOptionsError("XResolution must be an integer or floating point value."); }

            TIFFSetField(t.tif, TIFFTAG_XRESOLUTION, value);
        }

        options_map::const_iterator y_iter = opts.find("tiff:YResolution");
        if (x_iter != opts.end()) {
            double d;
            int i;
            float value;
            if (x_iter->second.get_int(i)) { value = i; }
            else if (x_iter->second.get_double(d)) { value = d; }
            else { throw WriteOptionsError("YResolution must be an integer or floating point value."); }

            TIFFSetField(t.tif, TIFFTAG_YRESOLUTION, value);
        }

        const uint16_t resolution_unit = get_optional_int(opts, "tiff:XResolutionUnit", uint16_t(-1));
        if (resolution_unit != uint16_t(-1)) {
            TIFFSetField(t.tif, TIFFTAG_RESOLUTIONUNIT, resolution_unit);
        }

        if (is_multi) {
            TIFFSetField(t.tif, TIFFTAG_SUBFILETYPE, FILETYPE_PAGE);
            TIFFSetField(t.tif, TIFFTAG_PAGENUMBER, i, n_pages);
        }

        for (uint32 r = 0; r != h; ++r) {
            void* rowp = im->rowp(r);
            if (copy_data) {
                std::memcpy(bufp, rowp, im->dim(1) * im->nbytes());
                rowp = bufp;
            }
            if (TIFFWriteScanline(t.tif, rowp, r) == -1) {
                throw CannotWriteError("imread.imsave._tiff: Error writing TIFF file");
            }
        }
        if (is_multi) {
            if (!TIFFWriteDirectory(t.tif)) {
                throw CannotWriteError("TIFFWriteDirectory failed");
            }
        }
    }
    TIFFFlush(t.tif);
}
Ejemplo n.º 5
0
void
TIFFCleanup(TIFF* tif)
{
	/*
         * Flush buffered data and directory (if dirty).
         */
	if (tif->tif_mode != O_RDONLY)
		TIFFFlush(tif);
	(*tif->tif_cleanup)(tif);
	TIFFFreeDirectory(tif);

	if (tif->tif_dirlist)
		_TIFFfree(tif->tif_dirlist);

	/*
         * Clean up client info links.
         */
	while( tif->tif_clientinfo )
	{
		TIFFClientInfoLink *psLink = tif->tif_clientinfo;

		tif->tif_clientinfo = psLink->next;
		_TIFFfree( psLink->name );
		_TIFFfree( psLink );
	}

	if (tif->tif_rawdata && (tif->tif_flags&TIFF_MYBUFFER))
		_TIFFfree(tif->tif_rawdata);
	if (isMapped(tif))
		TIFFUnmapFileContents(tif, tif->tif_base, (toff_t)tif->tif_size);

	/*
         * Clean up custom fields.
         */
	if (tif->tif_fields && tif->tif_nfields > 0) {
		uint32 i;

		for (i = 0; i < tif->tif_nfields; i++) {
			TIFFField *fld = tif->tif_fields[i];
			if (fld->field_bit == FIELD_CUSTOM &&
			    strncmp("Tag ", fld->field_name, 4) == 0) {
				_TIFFfree(fld->field_name);
				_TIFFfree(fld);
			}
		}

		_TIFFfree(tif->tif_fields);
	}

        if (tif->tif_nfieldscompat > 0) {
                uint32 i;

                for (i = 0; i < tif->tif_nfieldscompat; i++) {
                        if (tif->tif_fieldscompat[i].allocated_size)
                                _TIFFfree(tif->tif_fieldscompat[i].fields);
                }
                _TIFFfree(tif->tif_fieldscompat);
        }

	_TIFFfree(tif);
}
Ejemplo n.º 6
0
void TifWriter::flush()
{
	TIFFFlush(m_tiff);
}
Ejemplo n.º 7
0
int ImagingLibTiffEncode(Imaging im, ImagingCodecState state, UINT8* buffer, int bytes) {
    /* One shot encoder. Encode everything to the tiff in the clientstate.
       If we're running off of a FD, then run once, we're good, everything
       ends up in the file, we close and we're done.

       If we're going to memory, then we need to write the whole file into memory, then
       parcel it back out to the pystring buffer bytes at a time.

    */

    TIFFSTATE *clientstate = (TIFFSTATE *)state->context;
    TIFF *tiff = clientstate->tiff;

    TRACE(("in encoder: bytes %d\n", bytes));
    TRACE(("State: count %d, state %d, x %d, y %d, ystep %d\n", state->count, state->state,
           state->x, state->y, state->ystep));
    TRACE(("State: xsize %d, ysize %d, xoff %d, yoff %d \n", state->xsize, state->ysize,
           state->xoff, state->yoff));
    TRACE(("State: bits %d, bytes %d \n", state->bits, state->bytes));
    TRACE(("Buffer: %p: %c%c%c%c\n", buffer, (char)buffer[0], (char)buffer[1],(char)buffer[2], (char)buffer[3]));
    TRACE(("State->Buffer: %c%c%c%c\n", (char)state->buffer[0], (char)state->buffer[1],(char)state->buffer[2], (char)state->buffer[3]));
    TRACE(("Image: mode %s, type %d, bands: %d, xsize %d, ysize %d \n",
           im->mode, im->type, im->bands, im->xsize, im->ysize));
    TRACE(("Image: image8 %p, image32 %p, image %p, block %p \n",
           im->image8, im->image32, im->image, im->block));
    TRACE(("Image: pixelsize: %d, linesize %d \n",
           im->pixelsize, im->linesize));

    dump_state(clientstate);

    if (state->state == 0) {
        TRACE(("Encoding line bt line"));
        while(state->y < state->ysize){
            state->shuffle(state->buffer,
                           (UINT8*) im->image[state->y + state->yoff] +
                           state->xoff * im->pixelsize,
                           state->xsize);

            if (TIFFWriteScanline(tiff, (tdata_t)(state->buffer), (uint32)state->y, 0) == -1) {
                TRACE(("Encode Error, row %d\n", state->y));
                state->errcode = IMAGING_CODEC_BROKEN;
                TIFFClose(tiff);
                if (!clientstate->fp){
                    free(clientstate->data);
                }
                return -1;
            }
            state->y++;
        }

        if (state->y == state->ysize) {
            state->state=1;

            TRACE(("Flushing \n"));
            if (!TIFFFlush(tiff)) {
                TRACE(("Error flushing the tiff"));
                // likely reason is memory.
                state->errcode = IMAGING_CODEC_MEMORY;
                TIFFClose(tiff);
                if (!clientstate->fp){
                    free(clientstate->data);
                }
                return -1;
            }
            TRACE(("Closing \n"));
            TIFFClose(tiff);
            // reset the clientstate metadata to use it to read out the buffer.
            clientstate->loc = 0;
            clientstate->size = clientstate->eof; // redundant?
        }
    }

    if (state->state == 1 && !clientstate->fp) {
        int read = (int)_tiffReadProc(clientstate, (tdata_t)buffer, (tsize_t)bytes);
        TRACE(("Buffer: %p: %c%c%c%c\n", buffer, (char)buffer[0], (char)buffer[1],(char)buffer[2], (char)buffer[3]));
        if (clientstate->loc == clientstate->eof) {
            TRACE(("Hit EOF, calling an end, freeing data"));
            state->errcode = IMAGING_CODEC_END;
            free(clientstate->data);
        }
        return read;
    }

    state->errcode = IMAGING_CODEC_END;
    return 0;
}