diff options
author | Pixel <pixel@nobis-crew.org> | 2009-11-04 11:56:41 -0800 |
---|---|---|
committer | Pixel <pixel@nobis-crew.org> | 2009-11-04 11:59:33 -0800 |
commit | d577d991b97ae2b5ee1af23641bcffc3f83af5b2 (patch) | |
tree | 590639d50205d1bcfaff2a7d2dc6ebf3f373c7ed /iup/src/iup_image.c |
Initial import. Contains the im, cd and iup librairies, and a "working" Makefile for them under linux.
Diffstat (limited to 'iup/src/iup_image.c')
-rwxr-xr-x | iup/src/iup_image.c | 1017 |
1 files changed, 1017 insertions, 0 deletions
diff --git a/iup/src/iup_image.c b/iup/src/iup_image.c new file mode 100755 index 0000000..12b1169 --- /dev/null +++ b/iup/src/iup_image.c @@ -0,0 +1,1017 @@ +/** \file + * \brief Image Resource. + * + * See Copyright Notice in "iup.h" + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <memory.h> + +#include "iup.h" + +#include "iup_object.h" +#include "iup_attrib.h" +#include "iup_str.h" +#include "iup_image.h" +#include "iup_assert.h" +#include "iup_stdcontrols.h" + + +typedef struct _IimageStock +{ + iupImageStockCreateFunc func; + Ihandle* image; /* cache image */ + const char* native_name; /* used to map to GTK stock images */ +} IimageStock; + +static Itable *istock_table = NULL; /* the function hast table indexed by the name string */ + +void iupImageStockInit(void) +{ + istock_table = iupTableCreate(IUPTABLE_STRINGINDEXED); +} + +void iupImageStockFinish(void) +{ + char* name = iupTableFirst(istock_table); + while (name) + { + IimageStock* istock = (IimageStock*)iupTableGetCurr(istock_table); + if (iupObjectCheck(istock->image)) + IupDestroy(istock->image); + free(istock); + name = iupTableNext(istock_table); + } + + iupTableDestroy(istock_table); + istock_table = NULL; +} + +void iupImageStockSet(const char *name, iupImageStockCreateFunc func, const char* native_name) +{ + IimageStock* istock = (IimageStock*)iupTableGet(istock_table, name); + if (istock) + free(istock); /* overwrite a previous registration */ + + istock = (IimageStock*)malloc(sizeof(IimageStock)); + istock->func = func; + istock->image = NULL; + istock->native_name = native_name; + + iupTableSet(istock_table, name, (void*)istock, IUPTABLE_POINTER); +} + +static void iImageStockGet(const char* name, Ihandle* *ih, const char* *native_name) +{ + IimageStock* istock = (IimageStock*)iupTableGet(istock_table, name); + if (istock) + { + if (istock->image) + *ih = istock->image; + else if (istock->native_name) + *native_name = istock->native_name; + else if (istock->func) + { + istock->image = istock->func(); + *ih = istock->image; + } + } +} + +void iupImageStockLoad(const char *name) +{ + /* Used only in iupImageLibLoadAll */ + const char* native_name = NULL; + Ihandle* ih = NULL; + iImageStockGet(name, &ih, &native_name); + if (ih) + IupSetHandle(name, ih); + else if (native_name) + { + /* dummy image to save the GTK stock name */ + void* handle = iupdrvImageLoad(native_name, IUPIMAGE_IMAGE); + if (handle) + { + int w, h, bpp; + iupdrvImageGetInfo(handle, &w, &h, &bpp); + if (bpp == 32) + ih = IupImageRGBA(w,h,NULL); + else + ih = IupImageRGB(w,h,NULL); + IupSetHandle(native_name, ih); + } + } +} + + +/**************************************************************************************************/ +/**************************************************************************************************/ + + +int iupImageNormBpp(int bpp) +{ + if (bpp <= 8) return 8; + if (bpp <= 24) return 24; + return 32; +} + +static void iupColorSet(iupColor *c, unsigned char r, unsigned char g, unsigned char b, unsigned char a) +{ + c->r = r; + c->g = g; + c->b = b; + c->a = a; +} + +int iupImageInitColorTable(Ihandle *ih, iupColor* colors, int *colors_count) +{ + char attr[6], *value; + unsigned char red, green, blue; + int i, has_alpha = 0; + static iupColor default_colors[] = { + { 0,0,0,255 }, { 128,0,0,255 }, { 0,128,0,255 }, { 128,128,0,255 }, + { 0,0,128,255 }, { 128,0,128,255 }, { 0,128,128,255 }, { 192,192,192,255 }, + { 128,128,128,255 }, { 255,0,0,255 }, { 0,255,0,255 }, { 255,255,0,255 }, + { 0,0,255,255 }, { 255,0,255,255 }, { 0,255,255,255 }, { 255,255,255,255 } }; + + memset(colors, 0, sizeof(iupColor)*256); + + for (i=0;i<16;i++) + { + sprintf(attr, "%d", i); + value = iupAttribGet(ih, attr); + + if (value) + { + if (iupStrEqual(value, "BGCOLOR")) + { + iupColorSet(&colors[i], 0, 0, 0, 0); + has_alpha = 1; + } + else + { + if (!iupStrToRGB(value, &red, &green, &blue)) + iupColorSet(&colors[i], default_colors[i].r, default_colors[i].g, default_colors[i].b, 255); + else + iupColorSet(&colors[i], red, green, blue, 255); + } + } + else + { + iupColorSet(&colors[i], default_colors[i].r, default_colors[i].g, default_colors[i].b, 255); + } + } + + for (;i<256;i++) + { + sprintf(attr, "%d", i); + value = iupAttribGet(ih, attr); + if (!value) + break; + + if (iupStrEqual(value, "BGCOLOR")) + { + iupColorSet(&colors[i], 0, 0, 0, 0); + has_alpha = 1; + } + else + { + if (!iupStrToRGB(value, &red, &green, &blue)) + break; + + iupColorSet(&colors[i], red, green, blue, 255); + } + } + + if (colors_count) *colors_count = i; + + return has_alpha; +} + +void iupImageInitNonBgColors(Ihandle* ih, unsigned char *colors) +{ + char attr[6], *value; + int i; + + memset(colors, 0, 256); + + for (i=0;i<16;i++) + { + sprintf(attr, "%d", i); + value = iupAttribGet(ih, attr); + if (!iupStrEqual(value, "BGCOLOR")) + colors[i] = 1; + } + + for (;i<256;i++) + { + sprintf(attr, "%d", i); + value = iupAttribGet(ih, attr); + if (!value) + break; + + if (!iupStrEqual(value, "BGCOLOR")) + colors[i] = 1; + } +} + +void iupImageColorMakeInactive(unsigned char *r, unsigned char *g, unsigned char *b, unsigned char bg_r, unsigned char bg_g, unsigned char bg_b) +{ + if (*r==bg_r && *g==bg_g && *b==bg_b) /* preserve colors identical to the background color */ + { + *r = bg_r; + *g = bg_g; + *b = bg_b; + } + else + { + int ir = 0, ig = 0, ib = 0, + i = (*r+*g+*b)/3, + bg_i = (bg_r+bg_g+bg_b)/3; + + if (bg_i) + { + ir = (bg_r*i)/bg_i; + ig = (bg_g*i)/bg_i; + ib = (bg_b*i)/bg_i; + } + +#define LIGHTER(_c) ((255 + _c)/2) + ir = LIGHTER(ir); + ig = LIGHTER(ig); + ib = LIGHTER(ib); + + *r = iupBYTECROP(ir); + *g = iupBYTECROP(ig); + *b = iupBYTECROP(ib); + } +} + + +/**************************************************************************************************/ +/**************************************************************************************************/ + + +void* iupImageGetMask(const char* name) +{ + void* mask; + Ihandle *ih; + + if (!name) + return NULL; + + /* get handle from name */ + ih = IupGetHandle(name); + if (!ih) + return NULL; + + /* Check for an already created icon */ + mask = iupAttribGet(ih, "_IUPIMAGE_MASK"); + if (mask) + return mask; + + /* Not created, tries to create the mask */ + mask = iupdrvImageCreateMask(ih); + + /* save the pixbuf */ + iupAttribSetStr(ih, "_IUPIMAGE_MASK", (char*)mask); + + return mask; +} + +void* iupImageGetIcon(const char* name) +{ + void* icon; + Ihandle *ih; + + if (!name) + return NULL; + + /* Check first in the system resources. */ + icon = iupdrvImageLoad(name, IUPIMAGE_ICON); + if (icon) + return icon; + + /* get handle from name */ + ih = IupGetHandle(name); + if (!ih) + return NULL; + + /* Check for an already created icon */ + icon = iupAttribGet(ih, "_IUPIMAGE_ICON"); + if (icon) + return icon; + + /* Not created, tries to create the icon */ + icon = iupdrvImageCreateIcon(ih); + + /* save the pixbuf */ + iupAttribSetStr(ih, "_IUPIMAGE_ICON", (char*)icon); + + return icon; +} + +void* iupImageGetCursor(const char* name) +{ + void* cursor; + Ihandle *ih; + + if (!name) + return NULL; + + /* Check first in the system resources. */ + cursor = iupdrvImageLoad(name, IUPIMAGE_CURSOR); + if (cursor) + return cursor; + + /* get handle from name */ + ih = IupGetHandle(name); + if (!ih) + return NULL; + + /* Check for an already created cursor */ + cursor = iupAttribGet(ih, "_IUPIMAGE_CURSOR"); + if (cursor) + return cursor; + + /* Not created, tries to create the cursor */ + cursor = iupdrvImageCreateCursor(ih); + + /* save the pixbuf */ + iupAttribSetStr(ih, "_IUPIMAGE_CURSOR", (char*)cursor); + + return cursor; +} + +void iupImageGetInfo(const char* name, int *w, int *h, int *bpp) +{ + void* handle; + Ihandle *ih; + + if (!name) + return; + + /* Check first in the system resources. */ + handle = iupdrvImageLoad(name, IUPIMAGE_IMAGE); + if (handle) + { + iupdrvImageGetInfo(handle, w, h, bpp); + return; + } + + /* get handle from name */ + ih = IupGetHandle(name); + if (!ih) + { + /* Check in the stock images. */ + const char* native_name = NULL; + iImageStockGet(name, &ih, &native_name); + + if (native_name) + { + handle = iupdrvImageLoad(native_name, IUPIMAGE_IMAGE); + if (handle) + { + iupdrvImageGetInfo(handle, w, h, bpp); + return; + } + } + + if (!ih) + return; + } + + if (w) *w = ih->currentwidth; + if (h) *h = ih->currentheight; + if (bpp) *bpp = IupGetInt(ih, "BPP"); +} + +void* iupImageGetImage(const char* name, Ihandle* ih_parent, int make_inactive) +{ + char cache_name[100] = "_IUPIMAGE_IMAGE"; + char* bgcolor; + void* handle; + Ihandle *ih; + int bg_concat = 0; + + if (!name) + return NULL; + + /* Check first in the system resources. */ + handle = iupdrvImageLoad(name, IUPIMAGE_IMAGE); + if (handle) + return handle; + + /* get handle from name */ + ih = IupGetHandle(name); + if (!ih) + { + /* Check in the stock images. */ + const char* native_name = NULL; + iImageStockGet(name, &ih, &native_name); + + if (native_name) + { + handle = iupdrvImageLoad(native_name, IUPIMAGE_IMAGE); + if (handle) + return handle; + } + + if (!ih) + return NULL; + } + + bgcolor = iupAttribGet(ih, "BGCOLOR"); + if (ih_parent && !bgcolor) + bgcolor = IupGetAttribute(ih_parent, "BGCOLOR"); /* Use IupGetAttribute to use inheritance and native implementation */ + + if (make_inactive) + strcat(cache_name, "_INACTIVE"); + + if (iupAttribGet(ih, "_IUP_BGCOLOR_DEPEND") && bgcolor) + { + strcat(cache_name, "("); + strcat(cache_name, bgcolor); + strcat(cache_name, ")"); + bg_concat = 1; + } + + /* Check for an already created native image */ + handle = (void*)iupAttribGet(ih, cache_name); + if (handle) + return handle; + + if (ih_parent && iupAttribGetStr(ih_parent, "FLAT_ALPHA")) + iupAttribSetStr(ih, "FLAT_ALPHA", "1"); + + /* Creates the native image */ + handle = iupdrvImageCreateImage(ih, bgcolor, make_inactive); + + if (ih_parent && iupAttribGetStr(ih_parent, "FLAT_ALPHA")) + iupAttribSetStr(ih, "FLAT_ALPHA", NULL); + + if (iupAttribGet(ih, "_IUP_BGCOLOR_DEPEND") && bgcolor && !bg_concat) /* _IUP_BGCOLOR_DEPEND could be set during creation */ + { + strcat(cache_name, "("); + strcat(cache_name, bgcolor); + strcat(cache_name, ")"); + } + + /* save the native image in the cache */ + iupAttribSetStr(ih, cache_name, (char*)handle); + + return handle; +} + +void iupImageUpdateParent(Ihandle *ih) /* ih here is the element that contains images */ +{ + int inherit; + + /* Called when BGCOLOR is changed */ + /* it will re-create the image, if the case */ + + char* value = iupAttribGet(ih, "IMAGE"); + if (value) + iupClassObjectSetAttribute(ih, "IMAGE", value, &inherit); + + value = iupAttribGet(ih, "IMINACTIVE"); + if (value) + iupClassObjectSetAttribute(ih, "IMINACTIVE", value, &inherit); + + value = iupAttribGet(ih, "IMPRESS"); + if (value) + iupClassObjectSetAttribute(ih, "IMPRESS", value, &inherit); +} + +static char* iImageGetWidthAttrib(Ihandle *ih) +{ + char* str = iupStrGetMemory(50); + sprintf(str, "%d", ih->currentwidth); + return str; +} + +static char* iImageGetHeightAttrib(Ihandle *ih) +{ + char* str = iupStrGetMemory(50); + sprintf(str, "%d", ih->currentheight); + return str; +} + +void iupImageClearCache(Ihandle* ih, void* handle) +{ + char *name; + void* cur_handle; + + name = iupTableFirst(ih->attrib); + while (name) + { + if (iupStrEqualPartial(name, "_IUPIMAGE_")) + { + cur_handle = iupTableGetCurr(ih->attrib); + if (cur_handle == handle) + { + iupTableRemoveCurr(ih->attrib); + return; + } + } + + name = iupTableNext(ih->attrib); + } +} + +static void iImageUnMapMethod(Ihandle* ih) +{ + char *name; + void* handle; + + handle = iupAttribGet(ih, "_IUPIMAGE_ICON"); + if (handle) + { + iupdrvImageDestroy(handle, IUPIMAGE_ICON); + iupAttribSetStr(ih, "_IUPIMAGE_ICON", NULL); + } + + handle = iupAttribGet(ih, "_IUPIMAGE_CURSOR"); + if (handle) + { + iupdrvImageDestroy(handle, IUPIMAGE_CURSOR); + iupAttribSetStr(ih, "_IUPIMAGE_CURSOR", NULL); + } + + /* the remaining images are all IUPIMAGE_IMAGE */ + name = iupTableFirst(ih->attrib); + while (name) + { + if (iupStrEqualPartial(name, "_IUPIMAGE_")) + { + handle = iupTableGetCurr(ih->attrib); + if (handle) iupdrvImageDestroy(handle, IUPIMAGE_IMAGE); + } + + name = iupTableNext(ih->attrib); + } +} + +static int iImageCreate(Ihandle* ih, void** params, int bpp) +{ + int width, height, channels, count; + unsigned char *imgdata; + + iupASSERT(params!=NULL); + if (!params) + return IUP_ERROR; + + width = (int)(params[0]); + height = (int)(params[1]); + + iupASSERT(width>0); + iupASSERT(height>0); + + if (width <= 0 || height <= 0) + return IUP_ERROR; + + ih->currentwidth = width; + ih->currentheight = height; + + channels = 1; + if (bpp == 24) + channels = 3; + else if (bpp == 32) + channels = 4; + + count = width*height*channels; + imgdata = (unsigned char *)malloc(count); + + if (((int)(params[2])==-1) || ((int)(params[3])==-1)) /* compacted in one pointer */ + { + if ((int)(params[2])!=-1) + memcpy(imgdata, params[2], count); + } + else /* one param for each element */ + { + int i; + for(i=0; i<count; i++) + { + imgdata[i] = (unsigned char)((int)(params[i+2])); + } + } + + iupAttribSetStr(ih, "WID", (char*)imgdata); + iupAttribSetInt(ih, "BPP", bpp); + iupAttribSetInt(ih, "CHANNELS", channels); + + return IUP_NOERROR; +} + +static int iImageCreateMethod(Ihandle* ih, void** params) +{ + return iImageCreate(ih, params, 8); +} + +static int iImageRGBCreateMethod(Ihandle* ih, void** params) +{ + return iImageCreate(ih, params, 24); +} + +static int iImageRGBACreateMethod(Ihandle* ih, void** params) +{ + return iImageCreate(ih, params, 32); +} + +static void iImageDestroyMethod(Ihandle* ih) +{ + unsigned char* imgdata = (unsigned char*)iupAttribGetStr(ih, "WID"); + if (imgdata) + { + iupAttribSetStr(ih, "WID", NULL); + free(imgdata); + } +} + +/******************************************************************************/ + +Ihandle* IupImage(int width, int height, const unsigned char *imgdata) +{ + void *params[4]; + params[0] = (void*)width; + params[1] = (void*)height; + params[2] = imgdata? (void*)imgdata: (void*)-1; + params[3] = (void*)-1; + return IupCreatev("image", params); +} + +Ihandle* IupImageRGB(int width, int height, const unsigned char *imgdata) +{ + void *params[4]; + params[0] = (void*)width; + params[1] = (void*)height; + params[2] = imgdata? (void*)imgdata: (void*)-1; + params[3] = (void*)-1; + return IupCreatev("imagergb", params); +} + +Ihandle* IupImageRGBA(int width, int height, const unsigned char *imgdata) +{ + void *params[4]; + params[0] = (void*)width; + params[1] = (void*)height; + params[2] = imgdata? (void*)imgdata: (void*)-1; + params[3] = (void*)-1; + return IupCreatev("imagergba", params); +} + +static Iclass* iImageGetClassBase(char* name, int (*create_func)(Ihandle* ih, void** params)) +{ + Iclass* ic = iupClassNew(NULL); + + ic->name = name; + ic->format = "iiC"; /* (int,int,unsigned char*) */ + ic->nativetype = IUP_TYPEIMAGE; + ic->childtype = IUP_CHILDNONE; + ic->is_interactive = 0; + + /* Class functions */ + ic->Create = create_func; + ic->Destroy = iImageDestroyMethod; + ic->Map = iupBaseTypeVoidMapMethod; + ic->UnMap = iImageUnMapMethod; + + /* Attribute functions */ + iupClassRegisterAttribute(ic, "WID", NULL, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NO_INHERIT|IUPAF_NO_STRING); + iupClassRegisterAttribute(ic, "WIDTH", iImageGetWidthAttrib, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "HEIGHT", iImageGetHeightAttrib, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "RASTERSIZE", iupBaseGetRasterSizeAttrib, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "BGCOLOR", NULL, NULL, IUPAF_SAMEASSYSTEM, "DLGBGCOLOR", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + + iupClassRegisterAttribute(ic, "BPP", NULL, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "CHANNELS", NULL, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + + iupClassRegisterAttribute(ic, "HOTSPOT", NULL, NULL, "0:0", NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + + return ic; +} + +Iclass* iupImageGetClass(void) +{ + return iImageGetClassBase("image", iImageCreateMethod); +} + +Iclass* iupImageRGBGetClass(void) +{ + return iImageGetClassBase("imagergb", iImageRGBCreateMethod); +} + +Iclass* iupImageRGBAGetClass(void) +{ + return iImageGetClassBase("imagergba", iImageRGBACreateMethod); +} + +static int SaveImageC(const char* file_name, Ihandle* ih, const char* name, FILE* packfile) +{ + int y, x, width, height, channels, linesize; + unsigned char* data; + FILE* file; + + if (packfile) + file = packfile; + else + file = fopen(file_name, "wb"); + + if (!file) + return 0; + + width = IupGetInt(ih, "WIDTH"); + height = IupGetInt(ih, "HEIGHT"); + channels = IupGetInt(ih, "CHANNELS"); + linesize = width*channels; + + data = (unsigned char*)IupGetAttribute(ih, "WID"); + + if (fprintf(file, "static Ihandle* load_image_%s(void)\n", name)<0) + { + if (!packfile) + fclose(file); + return 0; + } + + fprintf(file, "{\n"); + fprintf(file, " unsigned char imgdata[] = {\n"); + + for (y = 0; y < height; y++) + { + fprintf(file, " "); + + for (x = 0; x < linesize; x++) + { + if (x != 0) + fprintf(file, ", "); + + fprintf(file, "%d", (int)data[y*linesize+x]); + } + + if (y == height-1) + fprintf(file, "};\n\n"); + else + fprintf(file, ",\n"); + } + + if (channels == 1) + { + int c; + char str[20]; + char* color; + + fprintf(file, " Ihandle* image = IupImage(%d, %d, imgdata);\n\n", width, height); + + for (c = 0; c < 256; c++) + { + sprintf(str, "%d", c); + color = IupGetAttribute(ih, str); + if (!color) + break; + + fprintf(file, " IupSetAttribute(image, \"%d\", \"%s\");\n", c, color); + } + + fprintf(file, "\n"); + } + else if (channels == 3) + fprintf(file, " Ihandle* image = IupImageRGB(%d, %d, imgdata);\n", width, height); + else /* channels == 4 */ + fprintf(file, " Ihandle* image = IupImageRGBA(%d, %d, imgdata);\n", width, height); + + fprintf(file, " return image;\n"); + fprintf(file, "}\n\n"); + + if (!packfile) + fclose(file); + + return 1; +} + +static int SaveImageLua(const char* file_name, Ihandle* ih, const char* name, FILE* packfile) +{ + int y, x, width, height, channels, linesize; + unsigned char* data; + FILE* file; + + if (packfile) + file = packfile; + else + file = fopen(file_name, "wb"); + + if (!file) + return 0; + + width = IupGetInt(ih, "WIDTH"); + height = IupGetInt(ih, "HEIGHT"); + channels = IupGetInt(ih, "CHANNELS"); + linesize = width*channels; + + data = (unsigned char*)IupGetAttribute(ih, "WID"); + + if (fprintf(file, "function load_image_%s()\n", name)<0) + { + if (!packfile) + fclose(file); + return 0; + } + + if (channels == 1) + fprintf(file, " local %s = iup.image\n", name); + else if (channels == 3) + fprintf(file, " local %s = iup.imagergb\n", name); + else /* channels == 4 */ + fprintf(file, " local %s = iup.imagergba\n", name); + + fprintf(file, " {\n"); + + fprintf(file, " width = %d,\n", width); + fprintf(file, " height = %d,\n", height); + fprintf(file, " pixels = {\n"); + + for (y = 0; y < height; y++) + { + fprintf(file, " "); + for (x = 0; x < linesize; x++) + { + fprintf(file, "%d, ", (int)data[y*linesize+x]); + } + fprintf(file, "\n"); + } + + fprintf(file, " },\n"); + + if (channels == 1) + { + int c; + char* color; + unsigned int r, g, b; + char str[20]; + + fprintf(file, " colors = {\n"); + + for(c = 0; c < 256; c++) + { + sprintf(str, "%d", c); + color = IupGetAttribute(ih, str); + if (!color) + break; + + if (iupStrEqualNoCase(color, "BGCOLOR")) + fprintf(file, " \"BGCOLOR\",\n"); + else + { + sscanf(color, "%d %d %d", &r, &g, &b); + fprintf(file, " \"%d %d %d\",\n", r, g, b); + } + } + + fprintf(file, " }\n"); + } + + fprintf(file, " }\n"); + + fprintf(file, " return %s\n", name); + fprintf(file, "end\n\n"); + + if (!packfile) + fclose(file); + + return 1; +} + +static int SaveImageLED(const char* file_name, Ihandle* ih, const char* name, FILE* packfile) +{ + int y, x, width, height, channels, linesize; + unsigned char* data; + FILE* file; + + if (packfile) + file = packfile; + else + file = fopen(file_name, "wb"); + + if (!file) + return 0; + + width = IupGetInt(ih, "WIDTH"); + height = IupGetInt(ih, "HEIGHT"); + channels = IupGetInt(ih, "CHANNELS"); + linesize = width*channels; + + data = (unsigned char*)IupGetAttribute(ih, "WID"); + + if (channels == 1) + { + int c; + unsigned int r, g, b; + char str[20]; + char* color; + + if (fprintf(file, "%s = IMAGE\n", name)<0) + { + if (!packfile) + fclose(file); + return 0; + } + + fprintf(file, "[\n"); + for(c = 0; c < 256; c++) + { + sprintf(str, "%d", c); + color = IupGetAttribute(ih, str); + if (!color) + { + if (c < 16) + continue; + else + break; + } + + if (c != 0) + fprintf(file, ",\n"); + + if (iupStrEqualNoCase(color, "BGCOLOR")) + fprintf(file, " %d = \"BGCOLOR\"", c); + else + { + sscanf(color, "%d %d %d", &r, &g, &b); + fprintf(file, " %d = \"%d %d %d\"", c, r, g, b); + } + } + fprintf(file, "\n]\n"); + } + else if (channels == 3) + { + if (fprintf(file, "%s = IMAGERGB\n", name)<0) + { + if (!packfile) + fclose(file); + return 0; + } + } + else /* channels == 4 */ + { + if (fprintf(file, "%s = IMAGERGBA\n", name)<0) + { + if (!packfile) + fclose(file); + return 0; + } + } + + fprintf(file, "(%d, %d,\n", width, height); + + for (y = 0; y < height; y++) + { + fprintf(file, " "); + for (x = 0; x < linesize; x++) + { + if (y == height-1 && x==linesize-1) + fprintf(file, "%d", (int)data[y*linesize+x]); + else + fprintf(file, "%d, ", (int)data[y*linesize+x]); + } + fprintf(file, "\n"); + } + + fprintf(file, ")\n\n"); + + if (!packfile) + fclose(file); + + return 1; +} + +int iupSaveImageAsText(Ihandle* ih, FILE* packfile, const char* format, const char* name) +{ + int ret = 0; + if (iupStrEqualNoCase(format, "LED")) + ret = SaveImageLED(NULL, ih, name, packfile); + else if (iupStrEqualNoCase(format, "LUA")) + ret = SaveImageLua(NULL, ih, name, packfile); + else if (iupStrEqualNoCase(format, "C") || iupStrEqualNoCase(format, "H")) + ret = SaveImageC(NULL, ih, name, packfile); + return ret; +} + +int IupSaveImageAsText(Ihandle* ih, const char* file_name, const char* format, const char* name) +{ + int ret = 0; + if (!name) + { + name = IupGetName(ih); + if (!name) + name = "image"; + } + if (iupStrEqualNoCase(format, "LED")) + ret = SaveImageLED(file_name, ih, name, NULL); + else if (iupStrEqualNoCase(format, "LUA")) + ret = SaveImageLua(file_name, ih, name, NULL); + else if (iupStrEqualNoCase(format, "C") || iupStrEqualNoCase(format, "H")) + ret = SaveImageC(file_name, ih, name, NULL); + return ret; +} |