Alien-FreeImage

 view release on metacpan or  search on metacpan

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

	int    len;
	const char * description;
};

// for reserved opcodes
#define res(length) { "reserved", (length), "reserved for Apple use" }
#define RGB_LEN 6
#define WORD_LEN -1
#define NA 0

static OpDef optable[] =
{
/* 0x00 */  { "NOP",               0, "nop" },
/* 0x01 */  { "Clip",             NA, "clip" },
/* 0x02 */  { "BkPat",             8, "background pattern" },
/* 0x03 */  { "TxFont",            2, "text font (word)" },
/* 0x04 */  { "TxFace",            1, "text face (byte)" },
/* 0x05 */  { "TxMode",            2, "text mode (word)" },
/* 0x06 */  { "SpExtra",           4, "space extra (fixed point)" },
/* 0x07 */  { "PnSize",            4, "pen size (point)" },
/* 0x08 */  { "PnMode",            2, "pen mode (word)" },
/* 0x09 */  { "PnPat",             8, "pen pattern" },
/* 0x0a */  { "FillPat",           8, "fill pattern" },
/* 0x0b */  { "OvSize",            4, "oval size (point)" },
/* 0x0c */  { "Origin",            4, "dh, dv (word)" },
/* 0x0d */  { "TxSize",            2, "text size (word)" },
/* 0x0e */  { "FgColor",           4, "foreground color (longword)" },
/* 0x0f */  { "BkColor",           4, "background color (longword)" },
/* 0x10 */  { "TxRatio",           8, "numerator (point), denominator (point)" },
/* 0x11 */  { "Version",           1, "version (byte)" },
/* 0x12 */  { "BkPixPat",         NA, "color background pattern" },
/* 0x13 */  { "PnPixPat",         NA, "color pen pattern" },
/* 0x14 */  { "FillPixPat",       NA, "color fill pattern" },
/* 0x15 */  { "PnLocHFrac",        2, "fractional pen position" },
/* 0x16 */  { "ChExtra",           2, "extra for each character" },
/* 0x17 */  res(0),
/* 0x18 */  res(0),
/* 0x19 */  res(0),
/* 0x1a */  { "RGBFgCol",    RGB_LEN, "RGB foreColor" },
/* 0x1b */  { "RGBBkCol",    RGB_LEN, "RGB backColor" },
/* 0x1c */  { "HiliteMode",        0, "hilite mode flag" },
/* 0x1d */  { "HiliteColor", RGB_LEN, "RGB hilite color" },
/* 0x1e */  { "DefHilite",         0, "Use default hilite color" },
/* 0x1f */  { "OpColor",           6, "RGB OpColor for arithmetic modes" },
/* 0x20 */  { "Line",              8, "pnLoc (point), newPt (point)" },
/* 0x21 */  { "LineFrom",          4, "newPt (point)" },
/* 0x22 */  { "ShortLine",         6, "pnLoc (point, dh, dv (-128 .. 127))" },
/* 0x23 */  { "ShortLineFrom",     2, "dh, dv (-128 .. 127)" },
/* 0x24 */  res(WORD_LEN),
/* 0x25 */  res(WORD_LEN),
/* 0x26 */  res(WORD_LEN),
/* 0x27 */  res(WORD_LEN),
/* 0x28 */  { "LongText",         NA, "txLoc (point), count (0..255), text" },
/* 0x29 */  { "DHText",           NA, "dh (0..255), count (0..255), text" },
/* 0x2a */  { "DVText",           NA, "dv (0..255), count (0..255), text" },
/* 0x2b */  { "DHDVText",         NA, "dh, dv (0..255), count (0..255), text" },
/* 0x2c */  res(WORD_LEN),
/* 0x2d */  res(WORD_LEN),
/* 0x2e */  res(WORD_LEN),
/* 0x2f */  res(WORD_LEN),
/* 0x30 */  { "frameRect",         8, "rect" },
/* 0x31 */  { "paintRect",         8, "rect" },
/* 0x32 */  { "eraseRect",         8, "rect" },
/* 0x33 */  { "invertRect",        8, "rect" },
/* 0x34 */  { "fillRect",          8, "rect" },
/* 0x35 */  res(8),
/* 0x36 */  res(8),
/* 0x37 */  res(8),
/* 0x38 */  { "frameSameRect",     0, "rect" },
/* 0x39 */  { "paintSameRect",     0, "rect" },
/* 0x3a */  { "eraseSameRect",     0, "rect" },
/* 0x3b */  { "invertSameRect",    0, "rect" },
/* 0x3c */  { "fillSameRect",      0, "rect" },
/* 0x3d */  res(0),
/* 0x3e */  res(0),
/* 0x3f */  res(0),
/* 0x40 */  { "frameRRect",        8, "rect" },
/* 0x41 */  { "paintRRect",        8, "rect" },
/* 0x42 */  { "eraseRRect",        8, "rect" },
/* 0x43 */  { "invertRRect",       8, "rect" },
/* 0x44 */  { "fillRRrect",        8, "rect" },
/* 0x45 */  res(8),
/* 0x46 */  res(8),
/* 0x47 */  res(8),
/* 0x48 */  { "frameSameRRect",    0, "rect" },
/* 0x49 */  { "paintSameRRect",    0, "rect" },
/* 0x4a */  { "eraseSameRRect",    0, "rect" },
/* 0x4b */  { "invertSameRRect",   0, "rect" },
/* 0x4c */  { "fillSameRRect",     0, "rect" },
/* 0x4d */  res(0),
/* 0x4e */  res(0),
/* 0x4f */  res(0),
/* 0x50 */  { "frameOval",         8, "rect" },
/* 0x51 */  { "paintOval",         8, "rect" },
/* 0x52 */  { "eraseOval",         8, "rect" },
/* 0x53 */  { "invertOval",        8, "rect" },
/* 0x54 */  { "fillOval",          8, "rect" },
/* 0x55 */  res(8),
/* 0x56 */  res(8),
/* 0x57 */  res(8),
/* 0x58 */  { "frameSameOval",     0, "rect" },
/* 0x59 */  { "paintSameOval",     0, "rect" },
/* 0x5a */  { "eraseSameOval",     0, "rect" },
/* 0x5b */  { "invertSameOval",    0, "rect" },
/* 0x5c */  { "fillSameOval",      0, "rect" },
/* 0x5d */  res(0),
/* 0x5e */  res(0),
/* 0x5f */  res(0),
/* 0x60 */  { "frameArc",         12, "rect, startAngle, arcAngle" },
/* 0x61 */  { "paintArc",         12, "rect, startAngle, arcAngle" },
/* 0x62 */  { "eraseArc",         12, "rect, startAngle, arcAngle" },
/* 0x63 */  { "invertArc",        12, "rect, startAngle, arcAngle" },
/* 0x64 */  { "fillArc",          12, "rect, startAngle, arcAngle" },
/* 0x65 */  res(12),
/* 0x66 */  res(12),
/* 0x67 */  res(12),
/* 0x68 */  { "frameSameArc",      4, "rect, startAngle, arcAngle" },
/* 0x69 */  { "paintSameArc",      4, "rect, startAngle, arcAngle" },
/* 0x6a */  { "eraseSameArc",      4, "rect, startAngle, arcAngle" },
/* 0x6b */  { "invertSameArc",     4, "rect, startAngle, arcAngle" },
/* 0x6c */  { "fillSameArc",       4, "rect, startAngle, arcAngle" },
/* 0x6d */  res(4),
/* 0x6e */  res(4),
/* 0x6f */  res(4),
/* 0x70 */  { "framePoly",        NA, "poly" },
/* 0x71 */  { "paintPoly",        NA, "poly" },
/* 0x72 */  { "erasePoly",        NA, "poly" },
/* 0x73 */  { "invertPoly",       NA, "poly" },
/* 0x74 */  { "fillPoly",         NA, "poly" },
/* 0x75 */  res(NA),
/* 0x76 */  res(NA),
/* 0x77 */  res(NA),
/* 0x78 */  { "frameSamePoly",     0, "poly (NYI)" },
/* 0x79 */  { "paintSamePoly",     0, "poly (NYI)" },
/* 0x7a */  { "eraseSamePoly",     0, "poly (NYI)" },
/* 0x7b */  { "invertSamePoly",    0, "poly (NYI)" },
/* 0x7c */  { "fillSamePoly",      0, "poly (NYI)" },
/* 0x7d */  res(0),
/* 0x7e */  res(0),
/* 0x7f */  res(0),
/* 0x80 */  { "frameRgn",         NA, "region" },
/* 0x81 */  { "paintRgn",         NA, "region" },
/* 0x82 */  { "eraseRgn",         NA, "region" },
/* 0x83 */  { "invertRgn",        NA, "region" },
/* 0x84 */  { "fillRgn",          NA, "region" },
/* 0x85 */  res(NA),
/* 0x86 */  res(NA),
/* 0x87 */  res(NA),
/* 0x88 */  { "frameSameRgn",      0, "region (NYI)" },
/* 0x89 */  { "paintSameRgn",      0, "region (NYI)" },
/* 0x8a */  { "eraseSameRgn",      0, "region (NYI)" },
/* 0x8b */  { "invertSameRgn",     0, "region (NYI)" },
/* 0x8c */  { "fillSameRgn",       0, "region (NYI)" },
/* 0x8d */  res(0),
/* 0x8e */  res(0),
/* 0x8f */  res(0),
/* 0x90 */  { "BitsRect",         NA, "copybits, rect clipped" },
/* 0x91 */  { "BitsRgn",          NA, "copybits, rgn clipped" },
/* 0x92 */  res(WORD_LEN),
/* 0x93 */  res(WORD_LEN),
/* 0x94 */  res(WORD_LEN),
/* 0x95 */  res(WORD_LEN),
/* 0x96 */  res(WORD_LEN),
/* 0x97 */  res(WORD_LEN),
/* 0x98 */  { "PackBitsRect",     NA, "packed copybits, rect clipped" },
/* 0x99 */  { "PackBitsRgn",      NA, "packed copybits, rgn clipped" },
/* 0x9a */  { "Opcode_9A",        NA, "the mysterious opcode 9A" },
/* 0x9b */  res(WORD_LEN),
/* 0x9c */  res(WORD_LEN),
/* 0x9d */  res(WORD_LEN),
/* 0x9e */  res(WORD_LEN),
/* 0x9f */  res(WORD_LEN),
/* 0xa0 */  { "ShortComment",      2, "kind (word)" },
/* 0xa1 */  { "LongComment",      NA, "kind (word), size (word), data" }
};

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

struct MacRect
{
	WORD top;
	WORD left;
	WORD bottom;
	WORD right;
};

struct MacpixMap
{
	// Ptr baseAddr              // Not used in file.
	// short rowBytes            // read in seperatly.
	struct MacRect Bounds;
	WORD version;
	WORD packType;
	LONG packSize;
	LONG hRes;
	LONG vRes;
	WORD pixelType;
	WORD pixelSize;
	WORD cmpCount;
	WORD cmpSize;
	LONG planeBytes;
	LONG pmTable;
	LONG pmReserved;
};

struct MacRGBColour
{
	WORD red;
	WORD green;

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

}

static const char * DLL_CALLCONV
MimeType() {
	return "image/x-pict";
}

static BOOL DLL_CALLCONV
Validate(FreeImageIO *io, fi_handle handle) {
	if(io->seek_proc(handle, 522, SEEK_SET) == 0) {
		BYTE pict_signature[] = { 0x00, 0x11, 0x02, 0xFF, 0x0C, 0X00 };
		BYTE signature[6];

		if(io->read_proc(signature, 1, sizeof(pict_signature), handle)) {
			// v1.0 files have 0x11 (version operator) followed by 0x01 (version number)
			// v2.0 files have 0x0011 (version operator) followed by 0x02ff (version number)
			//   and additionally 0x0c00 as a header opcode
			// Currently, we are only supporting v2.0
			return (memcmp(pict_signature, signature, sizeof(pict_signature)) == 0);
		} else {
			return FALSE;
		}
	}

	return FALSE;
}

static BOOL DLL_CALLCONV
SupportsExportDepth(int depth) {
	return FALSE;
}

static BOOL DLL_CALLCONV 
SupportsExportType(FREE_IMAGE_TYPE type) {
	return FALSE;
}

static BOOL DLL_CALLCONV
SupportsICCProfiles() {
	return FALSE;
}

/**
This plugin decodes macintosh PICT files with 1,2,4,8,16 and 32 bits per pixel as well as PICT/JPEG. 
If an alpha channel is present in a 32-bit-PICT, it is decoded as well. 
The PICT format is a general picture file format and can contain a lot of other elements besides bitmaps. 
These elements are ignored.	
*/
static FIBITMAP * DLL_CALLCONV
Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
	char outputMessage[ outputMessageSize ] = "";
	FIBITMAP* dib = NULL;
	try {		
		// Skip empty 512 byte header.
		if ( !io->seek_proc(handle, 512, SEEK_CUR) == 0 )
			return NULL;
		
		// Read PICT header
		Read16( io, handle ); // Skip version 1 picture size
		
		MacRect frame;
		ReadRect( io, handle, &frame );

		BYTE b = 0;
		while ((b = Read8(io, handle)) == 0);
		if ( b != 0x11 ) {
			throw "invalid header: version number missing.";
		}
		
		int version = Read8( io, handle );
		if ( version == 2 && Read8( io, handle ) != 0xff ) {
			throw "invalid header: illegal version number.";
		}
		
		enum PICTType {none, op9a, jpeg, pixmap, bitmap};
		PICTType pictType = none;
		
		MacRect bounds;
		MacpixMap pixMap;
		int hRes = 0x480000; // in pixels/inch (72 by default == 0x480000 in fixed point)
		int vRes = 0x480000; // in pixels/inch (72 by default == 0x480000 in fixed point)
		WORD rowBytes = 0;
		BOOL isRegion = FALSE;
		BOOL done = FALSE;
		long currentPos = 0;

		while ( !done ) {
			WORD opcode = 0;

			// get the current stream position (used to avoid infinite loops)
			currentPos = io->tell_proc(handle);
			
			if ((version == 1) || ((io->tell_proc( handle ) % 2) != 0)) {
				// align to word for version 2
				opcode = Read8( io, handle );
			}
			if (version == 2) {
				opcode = Read16( io, handle );
			}
			
			if (opcode == 0xFF || opcode == 0xFFFF) {
				done = TRUE;
				throw "PICT contained only vector data!";
			}
			else if (opcode < 0xa2)	{				
				switch (opcode)	{
					case 0x01:
					{
						// skip clipping rectangle
						MacRect clipRect;
						WORD len = Read16( io, handle );

						if (len == 0x000a) { 
							/* null rgn */
							ReadRect( io, handle, &clipRect );
						} else {
							io->seek_proc(handle, len - 2, SEEK_CUR);
						}
						break;
					}						
					case 0x12:
					case 0x13:

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

						
						if ( rowBytes & 0x8000) {
							pictType = pixmap;
						} else {
							pictType = bitmap;						
						}
						done = TRUE;
						break;
					}
					case 0x9a:
					{
						// DirectBitsRect.
						Read32( io, handle );           // Skip fake len and fake EOF.
						Read16( io, handle );			// bogus row bytes.
						
						// Read in the PixMap fields.
						ReadRect( io, handle, &pixMap.Bounds );
						ReadPixmap( io, handle, &pixMap );
						
						// Ignore source & destination rectangle as well as transfer mode.
						MacRect dummy;
						ReadRect( io, handle, &dummy );
						ReadRect( io, handle, &dummy );
						WORD mode = Read16( io, handle );
						
						pictType=op9a;
						done = TRUE;
						break;
					}
					case 0xa1:
					{
						// long comment
						WORD type;
						WORD len;
						
						type = Read16( io, handle );
						len = Read16( io, handle);
						if (len > 0) {
							io->seek_proc(handle, len, SEEK_CUR);
						}
						break;
					}
					default:
						// No function => skip to next opcode
						if (optable[opcode].len == WORD_LEN) {
							WORD len = Read16( io, handle );
							io->seek_proc(handle, len, SEEK_CUR);
						} else {
							io->seek_proc(handle, optable[opcode].len, SEEK_CUR);
						}
						break;
				}
			}
			else if (opcode == 0xc00) {
				// version 2 header (26 bytes)
				WORD minorVersion = Read16( io, handle );	// always FFFE (-2) for extended version 2
				Read16( io, handle );						// reserved
				hRes = Read32( io, handle );				// original horizontal resolution in pixels/inch
				vRes = Read32( io, handle );				// original horizontal resolution in pixels/inch
				MacRect dummy;
				ReadRect( io, handle, &dummy );				// frame bounds at original resolution
				Read32( io, handle );						// reserved
			}
			else if (opcode == 0x8200) {
				// jpeg
				long opLen = Read32( io, handle );
				BOOL found = FALSE;
				int i = 0;
				
				// skip to JPEG header.
				while ( !found && i < opLen ) {
//					io->seek_proc( handle, 24, SEEK_CUR );
//					MacRect dummy;
//					ReadRect( io, handle, &dummy );
//					io->seek_proc( handle, 122, SEEK_CUR );
//					found = TRUE;
					BYTE data[ 2 ];
					if( io->read_proc( data, 2, 1, handle ) ) {
						io->seek_proc( handle, -2, SEEK_CUR );
						
						if ( data[0] == 0xFF && data[1] == 0xD8 ) {
							found = TRUE;
						} else {
							Read8( io, handle );
							i++;
						}
					}
				}
				
				if ( found ) {
					// Pass the data to the JPEG decoder.
					pictType = jpeg;
				} else {
					throw "PICT file contains unrecognized quicktime data.";
				}
				done = TRUE;
			}
			else if (opcode >= 0xa2 && opcode <= 0xaf) {
				// reserved
				WORD len = Read16( io, handle );
				io->seek_proc(handle, len, SEEK_CUR);
			}
			else if ((opcode >= 0xb0 && opcode <= 0xcf) || (opcode >= 0x8000 && opcode <= 0x80ff)) {
				// just a reserved opcode, no data
			}
			else if ((opcode >= 0xd0 && opcode <= 0xfe) || opcode >= 8100) {
				// reserved
				LONG len = Read32( io, handle );
				io->seek_proc(handle, len, SEEK_CUR);
			}
			else if (opcode >= 0x100 && opcode <= 0x7fff) {
				// reserved
				io->seek_proc(handle, ((opcode >> 7) & 255), SEEK_CUR);				
			}
			else {
				sprintf( outputMessage, "Can't handle opcode %x.\n", opcode );
				throw outputMessage;
			}

			if(currentPos == io->tell_proc(handle)) {
				// we probaly reached the end of file as we can no longer move forward ... 



( run in 0.930 second using v1.01-cache-2.11-cpan-df04353d9ac )