|
From: Robert K. <may...@us...> - 2001-06-06 21:22:53
|
Update of /cvsroot/bitcollider/bitcollider/image
In directory usw-pr-cvs1:/tmp/cvs-serv16801/image
Modified Files:
image.c
Log Message:
Checked in the new image plugin from delirium
Index: image.c
===================================================================
RCS file: /cvsroot/bitcollider/bitcollider/image/image.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** image.c 2001/05/31 21:57:38 1.1
--- image.c 2001/06/06 21:22:50 1.2
***************
*** 4,7 ****
--- 4,9 ----
*
* v0.1.0 - 30 May 2001 - Initial version, supports BMP (Bitmaps)
+ * v0.1.1 - 01 Jun 2001 - Added endian-safe portable input functions
+ * v0.2.0 - 04 Jun 2001 - Added support for GIF (CompuServe Graphics Interchange Format)
*/
***************
*** 14,19 ****
#include "plugin.h"
- /*-------------------------------------------------------------------------*/
PluginMethods *init_plugin(void);
static void image_shutdown_plugin(void);
--- 16,29 ----
#include "plugin.h"
+ /*--32-bit Specific Definitions of Portable Data Types---------------------*/
+
+ typedef unsigned char uint8;
+ typedef unsigned short uint16;
+ typedef unsigned uint32;
+
+ /*--Prototypes-------------------------------------------------------------*/
+
+ /* external plugin functions */
PluginMethods *init_plugin(void);
static void image_shutdown_plugin(void);
***************
*** 23,48 ****
static const char *image_get_version(void);
static char *image_get_error(void);
! static Attribute *image_file_analyze(const char *fileName);
! /*-------------------------------------------------------------------------*/
! #define PLUGIN_VERSION "0.1.0"
! #define PLUGIN_NAME "Image metadata (supports: BMP)"
#define NUM_ATTRS 4
! /*-------------------------------------------------------------------------*/
! typedef int int32;
! typedef unsigned uint32;
! typedef short int16;
! typedef unsigned short uint16;
! /*-------------------------------------------------------------------------*/
static SupportedFormat formats[] =
{
! { ".bmp", "BMP (Bitmap) format" },
! { NULL, NULL }
};
static char *errorString = NULL;
--- 33,73 ----
static const char *image_get_version(void);
static char *image_get_error(void);
! static Attribute *image_file_analyze(const char *fileName);
! /* datafile parsing functions */
! int parse_bmp(FILE *file, uint32 *width, uint32 *height, uint16 *bpp);
! int parse_gif(FILE *file, uint32 *width, uint32 *height, uint16 *bpp);
!
! /* endian-safe input functions */
! uint8 read_8(FILE *file);
! uint16 read_16_big_endian(FILE *file);
! uint16 read_16_little_endian(FILE *file);
! uint32 read_32_big_endian(FILE *file);
! uint32 read_32_little_endian(FILE *file);
! /*--Plugin Parameters------------------------------------------------------*/
!
! #define PLUGIN_VERSION "0.2.0"
! #define PLUGIN_NAME "Image metadata (BMP, GIF)"
#define NUM_ATTRS 4
! /*--Cross Platform Foo-----------------------------------------------------*/
! #ifdef _WIN32
! #define strcasecmp stricmp
! #undef WORDS_BIGENDIAN
! #else
! #include "../config.h"
! #endif
! /*--Plugin Info------------------------------------------------------------*/
static SupportedFormat formats[] =
{
! { ".bmp", "BMP (Windows Bitmap) image" },
! { ".gif", "GIF (CompuServe Graphics Interchange Format) image" },
! { NULL , NULL }
};
+
static char *errorString = NULL;
***************
*** 61,65 ****
};
! /*-------------------------------------------------------------------------*/
PluginMethods *init_plugin(void)
--- 86,90 ----
};
! /*--Externally-called Plugin Functions-------------------------------------*/
PluginMethods *init_plugin(void)
***************
*** 94,101 ****
Attribute *attrList;
char temp[100];
! uint16 type;
! int32 width;
! int32 height;
uint16 bpp;
--- 119,127 ----
Attribute *attrList;
char temp[100];
+ char *ext;
+ int errorcode = 1;
! uint32 width;
! uint32 height;
uint16 bpp;
***************
*** 104,141 ****
return NULL;
! attrList = malloc(sizeof(Attribute) * NUM_ATTRS);
! memset(attrList, 0, sizeof(Attribute) * NUM_ATTRS);
! /* read in the type header and check if it's a valid BMP */
! if(fread(&type, sizeof(uint16), 1, file) < 1)
! {
! fclose(file);
! return NULL;
! }
! /* type header must be "MB" ("BM" stored big-endian) */
! if(type != 0x4D42)
! {
! fclose(file);
! return NULL;
! }
! fseek(file, 16L, SEEK_CUR); /* seek to width info */
! if(fread(&width, sizeof(int32), 1, file) < 1)
! {
! fclose(file);
! return NULL;
! }
! if(fread(&height, sizeof(int32), 1, file) < 1) /* height immediately follows */
! {
! fclose(file);
! return NULL;
! }
! fseek(file, 2L, SEEK_CUR); /* seek to color depth (bpp) info */
! if(fread(&bpp, sizeof(uint16), 1, file) < 1)
! {
! fclose(file);
return NULL;
- }
sprintf(temp, "%d", width);
attrList[0].key = strdup("tag.image.width");
--- 130,149 ----
return NULL;
! ext = strrchr(fileName, '.');
! if(strcasecmp(ext,".bmp") == 0)
! errorcode = parse_bmp(file, &width, &height, &bpp);
! else if(strcasecmp(ext, ".gif") == 0)
! errorcode = parse_gif(file, &width, &height, &bpp);
! fclose(file);
!
! if(errorcode || width==0 || height==0 || bpp==0)
return NULL;
+ /* by this point we should have valid info, so return it */
+ attrList = malloc(sizeof(Attribute) * NUM_ATTRS);
+ memset(attrList, 0, sizeof(Attribute) * NUM_ATTRS);
+
sprintf(temp, "%d", width);
attrList[0].key = strdup("tag.image.width");
***************
*** 150,155 ****
attrList[2].value = strdup(temp);
- fclose(file);
-
return attrList;
}
--- 158,161 ----
***************
*** 175,176 ****
--- 181,290 ----
}
+ /*--Functions to Parse Files for Width/Height/BPP info---------------------*/
+
+ /* All functions return 0 on success and 1 if file is not a valid file of that type */
+
+ int parse_bmp(FILE *file, uint32 *width, uint32 *height, uint16 *bpp)
+ {
+ /* File must start with "BM" */
+ if(read_8(file) != 'B' || read_8(file) != 'M')
+ return 1;
+
+ fseek(file, 16L, SEEK_CUR);
+ *width = read_32_little_endian(file);
+
+ *height = read_32_little_endian(file);
+
+ fseek(file, 2L, SEEK_CUR);
+ *bpp = read_16_little_endian(file);
+
+ return 0;
+ }
+
+ int parse_gif(FILE *file, uint32 *width, uint32 *height, uint16 *bpp)
+ {
+ unsigned char packed;
+ uint16 bpp1, bpp2;
+
+ /* File must start with "GIF" */
+ if(read_8(file) != 'G' || read_8(file) != 'I' || read_8(file) != 'F')
+ return 1;
+
+ fseek(file, 3L, SEEK_CUR);
+ *width = (uint32) read_16_little_endian(file);
+
+ *height = (uint32) read_16_little_endian(file);
+
+ /* packed byte:
+ Bits 8 and 5 are flags we don't need to worry about;
+ bits 6-8 and 1-3 are 3-bit descriptions of the number of bits,
+ minus 1, of "color resolution" and "bits per pixel" respectively.
+ Usually these values are the same, but if they're not, take the
+ larger of the two to be "bpp," since this is what standard
+ image editing programs seem to do. I don't know why.
+ */
+ packed = read_8(file);
+ bpp1 = ((packed & 0x70) >> 4) + 1;
+ bpp2 = (packed & 0x07) + 1;
+
+ if(bpp1 > bpp2)
+ *bpp = bpp1;
+ else
+ *bpp = bpp2;
+
+ return 0;
+ }
+
+ /*--Endian-Safe Input Functions--------------------------------------------*/
+
+ uint8 read_8(FILE *file)
+ {
+ uint8 a;
+
+ if((a=getc(file))==(uint8)EOF)
+ return 0;
+
+ return a;
+ }
+
+ uint16 read_16_big_endian(FILE *file)
+ {
+ uint16 a,b;
+
+ if((a=getc(file))==(uint16)EOF || (b=getc(file))==(uint16)EOF)
+ return 0;
+
+ return ((a<<8) + b);
+ }
+
+ uint16 read_16_little_endian(FILE *file)
+ {
+ uint16 a,b;
+
+ if((a=getc(file))==(uint16)EOF || (b=getc(file))==(uint16)EOF)
+ return 0;
+
+ return ((b<<8) + a);
+ }
+
+ uint32 read_32_big_endian(FILE *file)
+ {
+ uint32 a,b,c,d;
+
+ if((a=getc(file))==(uint32)EOF || (b=getc(file))==(uint32)EOF ||
+ (c=getc(file))==(uint32)EOF || (d=getc(file))==(uint32)EOF)
+ return 0;
+
+ return ((a<<24) + (b<<16) + (c<<8) + d);
+ }
+
+ uint32 read_32_little_endian(FILE *file)
+ {
+ uint32 a,b,c,d;
+
+ if((a=getc(file))==(uint32)EOF || (b=getc(file))==(uint32)EOF ||
+ (c=getc(file))==(uint32)EOF || (d=getc(file))==(uint32)EOF)
+ return 0;
+
+ return ((d<<24) + (c<<16) + (b<<8) + a);
+ }
|