Alien-FreeImage
view release on metacpan or search on metacpan
src/Source/FreeImage/PluginPICT.cpp view on Meta::CPAN
// Plugin Implementation
// ==========================================================
static const char * DLL_CALLCONV
Format() {
return "PICT";
}
static const char * DLL_CALLCONV
Description() {
return "Macintosh PICT";
}
static const char * DLL_CALLCONV
Extension() {
return "pct,pict,pic";
}
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) {
src/Source/FreeImage/PluginPICT.cpp view on Meta::CPAN
case jpeg:
{
dib = FreeImage_LoadFromHandle( FIF_JPEG, io, handle );
break;
}
case pixmap:
{
// Decode version 2 pixmap
ReadRect( io, handle, &pixMap.Bounds );
ReadPixmap( io, handle, &pixMap );
bounds = pixMap.Bounds;
int width = bounds.right - bounds.left;
int height = bounds.bottom - bounds.top;
if ( pixMap.pixelSize > 8 ) {
dib = FreeImage_Allocate( width, height, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
} else {
dib = FreeImage_Allocate( width, height, 8);
}
hRes = pixMap.hRes << 16;
vRes = pixMap.vRes << 16;
break;
}
case bitmap:
{
// Decode version 1 bitmap: 1 bpp.
MacRect srcRect;
MacRect dstRect;
WORD width; // Width in pixels
WORD height; // Height in pixels
ReadRect( io, handle, &bounds );
ReadRect( io, handle, &srcRect );
ReadRect( io, handle, &dstRect );
width = bounds.right - bounds.left;
height = bounds.bottom - bounds.top;
dib = FreeImage_Allocate(width, height, 8);
break;
}
}
if ( dib ) {
// need to convert resolution figures from fixed point, pixels/inch
// to floating point, pixels/meter.
float hres_ppm = hRes * ((float)39.4 / (float)65536.0);
float vres_ppm = vRes * ((float)39.4 / (float)65536.0);
FreeImage_SetDotsPerMeterX( dib, (LONG)hres_ppm );
FreeImage_SetDotsPerMeterY( dib, (LONG)vres_ppm );
switch( pictType ) {
case op9a:
DecodeOp9a( io, handle, dib, &pixMap );
break;
case jpeg:
// Already decoded if the embedded format was valid.
break;
case pixmap:
DecodePixmap( io, handle, dib, isRegion, &pixMap, rowBytes );
break;
case bitmap:
DecodeBitmap( io, handle, dib, isRegion, &bounds, rowBytes );
break;
default:
throw "invalid pict type";
}
}
return dib;
}
catch(const char *message) {
FreeImage_Unload( dib );
FreeImage_OutputMessageProc(s_format_id, message);
}
return NULL;
}
// ==========================================================
// Init
// ==========================================================
void DLL_CALLCONV
InitPICT(Plugin *plugin, int format_id) {
s_format_id = format_id;
plugin->format_proc = Format;
plugin->description_proc = Description;
plugin->extension_proc = Extension;
plugin->regexpr_proc = NULL;
plugin->open_proc = NULL;
plugin->close_proc = NULL;
plugin->pagecount_proc = NULL;
plugin->pagecapability_proc = NULL;
plugin->load_proc = Load;
plugin->save_proc = NULL;
plugin->validate_proc = Validate;
plugin->mime_proc = MimeType;
plugin->supports_export_bpp_proc = SupportsExportDepth;
plugin->supports_export_type_proc = SupportsExportType;
plugin->supports_icc_profiles_proc = SupportsICCProfiles;
}
( run in 0.912 second using v1.01-cache-2.11-cpan-8450f2e95f3 )