Alien-FreeImage

 view release on metacpan or  search on metacpan

src/Source/FreeImage/PluginG3.cpp  view on Meta::CPAN

// ==========================================================
// G3 Fax Loader
//
// Design and implementation by
// - Hervé Drolon (drolon@infonie.fr)
// - Petr Pytelka (pyta@lightcomp.com)
//
// This file is part of FreeImage 3
//
// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
// THIS DISCLAIMER.
//
// Use at your own risk!
// ==========================================================

#include "../LibTIFF4/tiffiop.h"

#include "FreeImage.h"
#include "Utilities.h"

// ==========================================================
// Plugin Interface
// ==========================================================

static int s_format_id;

// ==========================================================
//   Constant/Macro declarations
// ==========================================================

#define G3_DEFAULT_WIDTH	1728

#define TIFFhowmany8(x) (((x)&0x07)?((uint32)(x)>>3)+1:(uint32)(x)>>3)

// ==========================================================
//   libtiff interface 
// ==========================================================

static tmsize_t 
_g3ReadProc(thandle_t handle, void *buf, tmsize_t size) {
	// returns an error when reading the TIFF header
	return 0;
}

static tmsize_t
_g3WriteProc(thandle_t handle, void *buf, tmsize_t size) {
	// returns ok when writing the TIFF header
	return size;
}

static toff_t
_g3SeekProc(thandle_t handle, toff_t off, int whence) {
	return 0;
}

static int
_g3CloseProc(thandle_t handle) {
	return 0;
}

static toff_t
_g3SizeProc(thandle_t handle) {
	return 0;
}

static int
_g3MapProc(thandle_t, void** base, toff_t* size) {
	return 0;
}

static void
_g3UnmapProc(thandle_t, void* base, toff_t size) {
}

// --------------------------------------------------------------

static tmsize_t
G3GetFileSize(FreeImageIO *io, fi_handle handle) {
    long currentPos = io->tell_proc(handle);
    io->seek_proc(handle, 0, SEEK_END);
    long fileSize = io->tell_proc(handle);
    io->seek_proc(handle, currentPos, SEEK_SET);
    return fileSize;
}

static BOOL 
G3ReadFile(FreeImageIO *io, fi_handle handle, uint8 *tif_rawdata, tmsize_t tif_rawdatasize) {
	return ((tmsize_t)(io->read_proc(tif_rawdata, (unsigned)tif_rawdatasize, 1, handle) * tif_rawdatasize) == tif_rawdatasize);
}

// ==========================================================
// Internal functions
// ==========================================================

static int 
copyFaxFile(FreeImageIO *io, fi_handle handle, TIFF* tifin, uint32 xsize, int stretch, FIMEMORY *memory) {
	BYTE *rowbuf = NULL;
	BYTE *refbuf = NULL;
	uint32 row;
	uint16 badrun;
	uint16	badfaxrun;
	uint32	badfaxlines;
	int ok;

	try {

		uint32 linesize = TIFFhowmany8(xsize);
		rowbuf = (BYTE*) _TIFFmalloc(linesize);
		refbuf = (BYTE*) _TIFFmalloc(linesize);
		if (rowbuf == NULL || refbuf == NULL) {
			throw FI_MSG_ERROR_MEMORY;
		}

		tifin->tif_rawdatasize = G3GetFileSize(io, handle);
		tifin->tif_rawdata = (tidata_t) _TIFFmalloc(tifin->tif_rawdatasize);
		if (tifin->tif_rawdata == NULL) {
			throw FI_MSG_ERROR_MEMORY;
		}
			
		if(!G3ReadFile(io, handle, tifin->tif_rawdata, tifin->tif_rawdatasize)) {
			throw "Read error at scanline 0";
		}
		tifin->tif_rawcp = tifin->tif_rawdata;
		tifin->tif_rawcc = tifin->tif_rawdatasize;

		(*tifin->tif_setupdecode)(tifin);
		(*tifin->tif_predecode)(tifin, (uint16) 0);
		tifin->tif_row = 0;
		badfaxlines = 0;
		badfaxrun = 0;

		_TIFFmemset(refbuf, 0, linesize);
		row = 0;
		badrun = 0;		// current run of bad lines 
		while (tifin->tif_rawcc > 0) {
			ok = (*tifin->tif_decoderow)(tifin, rowbuf, linesize, 0);
			if (!ok) {
				badfaxlines++;
				badrun++;
				// regenerate line from previous good line 
				_TIFFmemcpy(rowbuf, refbuf, linesize);
			} else {
				if (badrun > badfaxrun)
					badfaxrun = badrun;
				badrun = 0;
				_TIFFmemcpy(refbuf, rowbuf, linesize);
			}
			tifin->tif_row++;

			FreeImage_WriteMemory(rowbuf, linesize, 1, memory);
			row++;
			if (stretch) {
				FreeImage_WriteMemory(rowbuf, linesize, 1, memory);
				row++;
			}
		}
		if (badrun > badfaxrun)
			badfaxrun = badrun;

		_TIFFfree(tifin->tif_rawdata);
		tifin->tif_rawdata = NULL;

		_TIFFfree(rowbuf);
		_TIFFfree(refbuf);

		/*
		if (verbose) {
			fprintf(stderr, "%d rows in input\n", rows);
			fprintf(stderr, "%ld total bad rows\n", (long) badfaxlines);
			fprintf(stderr, "%d max consecutive bad rows\n", badfaxrun);
		}
		*/

	} catch(const char *message) {
		if(rowbuf) _TIFFfree(rowbuf);
		if(refbuf) _TIFFfree(refbuf);
		if(tifin->tif_rawdata) {
			_TIFFfree(tifin->tif_rawdata);
			tifin->tif_rawdata = NULL;
		}
		FreeImage_OutputMessageProc(s_format_id, message);



( run in 0.911 second using v1.01-cache-2.11-cpan-5735350b133 )