Alien-FreeImage

 view release on metacpan or  search on metacpan

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

// ==========================================================
// XBM Loader
//
// Design and implementation by
// - Hervé Drolon <drolon@infonie.fr>
// part of the code adapted from the netPBM package (xbmtopbm.c)
//
// 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 "FreeImage.h"
#include "Utilities.h"

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

#define MAX_LINE	512

static const char *ERR_XBM_SYNTAX	= "Syntax error";
static const char *ERR_XBM_LINE		= "Line too long";
static const char *ERR_XBM_DECL		= "Unable to find a line in the file containing the start of C array declaration (\"static char\" or whatever)";
static const char *ERR_XBM_EOFREAD	= "EOF / read error";
static const char *ERR_XBM_WIDTH	= "Invalid width";
static const char *ERR_XBM_HEIGHT	= "Invalid height";
static const char *ERR_XBM_MEMORY	= "Out of memory";

/**
Get a string from a stream. 
Read the string from the current stream to the first newline character. 
The result stored in str is appended with a null character.
@param str Storage location for data 
@param n Maximum number of characters to read 
@param io Pointer to the FreeImageIO structure
@param handle Handle to the stream
@return Returns str. NULL is returned to indicate an error or an end-of-file condition.
*/
static char* 
readLine(char *str, int n, FreeImageIO *io, fi_handle handle) {
	char c;
	int count, i = 0;
	do {
		count = io->read_proc(&c, 1, 1, handle);
		str[i++] = c;
	} while((c != '\n') && (i < n));
	if(count <= 0)
		return NULL;
	str[i] = '\0';
	return str;
}

/**
Get a char from the stream
@param io Pointer to the FreeImageIO structure
@param handle Handle to the stream
@return Returns the next character in the stream
*/
static int 
readChar(FreeImageIO *io, fi_handle handle) {
	BYTE c;
	io->read_proc(&c, 1, 1, handle);
	return c;
}

/**
Read an XBM file into a buffer
@param io Pointer to the FreeImageIO structure
@param handle Handle to the stream
@param widthP (return value) Pointer to the bitmap width
@param heightP (return value) Pointer to the bitmap height
@param dataP (return value) Pointer to the bitmap buffer
@return Returns NULL if OK, returns an error message otherwise
*/
static const char* 
readXBMFile(FreeImageIO *io, fi_handle handle, int *widthP, int *heightP, char **dataP) {
	char line[MAX_LINE], name_and_type[MAX_LINE];
	char* ptr;
	char* t;
	int version = 0;
	int raster_length, v;
	int bytes, bytes_per_line, padding;
	int c1, c2, value1, value2;
	int hex_table[256];
	BOOL found_declaration;
	/* in scanning through the bitmap file, we have found the first
	 line of the C declaration of the array (the "static char ..."
	 or whatever line)
	 */
	BOOL eof;	// we've encountered end of file while searching file

	*widthP = *heightP = -1;

	found_declaration = FALSE;    // haven't found it yet; haven't even looked
	eof = FALSE;                  // haven't encountered end of file yet 
	
	while(!found_declaration && !eof) {

		if( readLine(line, MAX_LINE, io, handle) == NULL) {
			eof = TRUE;
		}
		else {
			if( strlen( line ) == MAX_LINE - 1 )
				return( ERR_XBM_LINE );
			if( sscanf(line, "#define %s %d", name_and_type, &v) == 2 ) {
				if( ( t = strrchr( name_and_type, '_' ) ) == NULL )
					t = name_and_type;
				else
					t++;
				if ( ! strcmp( "width", t ) )
					*widthP = v;
				else if ( ! strcmp( "height", t ) )
					*heightP = v;
				continue;
			}

			if( sscanf( line, "static short %s = {", name_and_type ) == 1 ) {
				version = 10;
				found_declaration = TRUE;
			}
			else if( sscanf( line, "static char %s = {", name_and_type ) == 1 ) {
				version = 11;
				found_declaration = TRUE;
			}
			else if(sscanf(line, "static unsigned char %s = {", name_and_type ) == 1 ) {
				version = 11;
				found_declaration = TRUE;
			}
		}
	}

	if(!found_declaration) 
		return( ERR_XBM_DECL );

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

// ==========================================================
// Plugin Implementation
// ==========================================================

static const char * DLL_CALLCONV
Format() {
	return "XBM";
}

static const char * DLL_CALLCONV
Description() {
	return "X11 Bitmap Format";
}

static const char * DLL_CALLCONV
Extension() {
	return "xbm";
}

static const char * DLL_CALLCONV
RegExpr() {
	return NULL;
}

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

static BOOL DLL_CALLCONV
Validate(FreeImageIO *io, fi_handle handle) {
	char magic[8];
	if(readLine(magic, 7, io, handle)) {
		if(strcmp(magic, "#define") == 0)
			return TRUE;
	}
	return FALSE;
}

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

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

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

static FIBITMAP * DLL_CALLCONV
Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
	char *buffer = NULL;
	int width, height;
	FIBITMAP *dib = NULL;

	try {

		// load the bitmap data
		const char* error = readXBMFile(io, handle, &width, &height, &buffer);
		// Microsoft doesn't implement throw between functions :(
		if(error) throw (char*)error;


		// allocate a new dib
		dib = FreeImage_Allocate(width, height, 1);
		if(!dib) throw (char*)ERR_XBM_MEMORY;

		// write the palette data
		RGBQUAD *pal = FreeImage_GetPalette(dib);
		pal[0].rgbRed = pal[0].rgbGreen = pal[0].rgbBlue = 0;
		pal[1].rgbRed = pal[1].rgbGreen = pal[1].rgbBlue = 255;

		// copy the bitmap
		BYTE *bP = (BYTE*)buffer;
		for(int y = 0; y < height; y++) {
			BYTE count = 0;
			BYTE mask = 1;
			BYTE *bits = FreeImage_GetScanLine(dib, height - 1 - y);

			for(int x = 0; x < width; x++) {
				if(count >= 8) {
					bP++;
					count = 0;
					mask = 1;
				}
				if(*bP & mask) {
					// Set bit(x, y) to 0
					bits[x >> 3] &= (0xFF7F >> (x & 0x7));
				} else {
					// Set bit(x, y) to 1
					bits[x >> 3] |= (0x80 >> (x & 0x7));
				}
				count++;
				mask <<= 1;
			}
			bP++;
		}

		free(buffer);
		return dib;

	} catch(const char *text) {
		if(buffer)	free(buffer);
		if(dib)		FreeImage_Unload(dib);
		FreeImage_OutputMessageProc(s_format_id, text);
		return NULL;
	}
}


// ==========================================================
//   Init
// ==========================================================

void DLL_CALLCONV
InitXBM(Plugin *plugin, int format_id) {
    s_format_id = format_id;

	plugin->format_proc = Format;
	plugin->description_proc = Description;
	plugin->extension_proc = Extension;



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