int imSaveMap(int width, int height, int format, unsigned char *map, int palette_count, long *palette, char *filename) { int error; char* new_format = i_format_old2new[format & 0x00FF]; imFile* ifile = imFileNew(filename, new_format, &error); if (!ifile) return error; if (format & 0xFF00) imFileSetInfo(ifile, NULL); else imFileSetInfo(ifile, "NONE"); imFileSetPalette(ifile, palette, palette_count); if (iOldResolutionCB) { double xres, yres; int res_unit; iOldResolutionCB(filename, &xres, &yres, &res_unit); float fxres=(float)xres, fyres=(float)yres; imFileSetAttribute(ifile, "XResolution", IM_FLOAT, 1, (void*)&fxres); imFileSetAttribute(ifile, "YResolution", IM_FLOAT, 1, (void*)&fyres); imFileSetAttribute(ifile, "ResolutionUnit", IM_INT, 1, (void*)&res_unit); } if (iOldTiffImageDescCB) { char img_desc[50]; iOldTiffImageDescCB(filename, img_desc); imFileSetAttribute(ifile, "Description", IM_BYTE, -1, (void*)img_desc); } if (iOldGifTranspIndexCB) { unsigned char transp_index; iOldGifTranspIndexCB(filename, &transp_index); imFileSetAttribute(ifile, "TransparencyIndex", IM_BYTE, 1, (void*)&transp_index); } error = imFileWriteImageInfo(ifile, width, height, IM_MAP, IM_BYTE); if (error) { imFileClose(ifile); return error; } if (iOldCounterCB) imCounterSetCallback(filename, iOldFileCounter); error = imFileWriteImageData(ifile, map); imFileClose(ifile); return error; }
static void iFileCheckConvertGray(imFile* ifile, imbyte* data) { int i, do_remap = 0; imbyte remap[256], r, g, b; // enforce the palette to only have grays in the correct order. for (i = 0; i < ifile->palette_count; i++) { imColorDecode(&r, &g, &b, ifile->palette[i]); if (r != i) { ifile->palette[i] = imColorEncode((imbyte)i, (imbyte)i, (imbyte)i); do_remap = 1; } remap[i] = r; } if (!do_remap) return; int count = ifile->width*ifile->height; for(i = 0; i < count; i++) { *data = remap[*data]; data++; } int transp_count; imbyte* transp_map = (imbyte*)imFileGetAttribute(ifile, "TransparencyMap", NULL, &transp_count); if (transp_map) { imbyte new_transp_map[256]; for (i=0; i<transp_count; i++) new_transp_map[i] = transp_map[remap[i]]; imFileSetAttribute(ifile, "TransparencyMap", IM_BYTE, transp_count, new_transp_map); } }
/*****************************************************************************\ file:SetAttribute(attrib, data_type, data) \*****************************************************************************/ static int imluaFileSetAttribute (lua_State *L) { int i, count = 0; void *data = NULL; imFile *ifile = imlua_checkfile(L, 1); const char *attrib = luaL_checkstring(L, 2); int data_type = luaL_checkinteger(L, 3); if (!lua_isnil(L, 4)) { if (!lua_isstring(L, 4)) { luaL_checktype(L, 4, LUA_TTABLE); count = imlua_getn(L, 4); data = malloc(imDataTypeSize(data_type) * count); } else if (data_type != IM_BYTE) luaL_argerror(L, 4, "if value is string, then data type must be byte"); switch (data_type) { case IM_BYTE: { if (lua_isstring(L, 4)) { const char* str = lua_tostring(L, 4); count = (int)strlen(str)+1; data = malloc(imDataTypeSize(data_type) * count); memcpy(data, str, count); } else { imbyte *d = (imbyte*) data; for (i = 0; i < count; i++) { lua_rawgeti(L, 4, i+1); d[i] = (imbyte) luaL_checkinteger(L, -1); lua_pop(L, 1); } } } break; case IM_SHORT: { short *d = (short*) data; for (i = 0; i < count; i++) { lua_rawgeti(L, 4, i+1); d[i] = (short) luaL_checkinteger(L, -1); lua_pop(L, 1); } } break; case IM_USHORT: { imushort *d = (imushort*) data; for (i = 0; i < count; i++) { lua_rawgeti(L, 4, i+1); d[i] = (imushort) luaL_checkinteger(L, -1); lua_pop(L, 1); } } break; case IM_INT: { int *d = (int*) data; for (i = 0; i < count; i++) { lua_rawgeti(L, 4, i+1); d[i] = luaL_checkinteger(L, -1); lua_pop(L, 1); } } break; case IM_FLOAT: { float *d = (float*) data; for (i = 0; i < count; i++) { lua_rawgeti(L, 4, i+1); d[i] = (float) luaL_checknumber(L, -1); lua_pop(L, 1); } } break; case IM_CFLOAT: { float *data_float = (float*) data; for (i = 0; i < count; i++) { int two; float *value = imlua_toarrayfloat(L, -1, &two, 1); if (two != 2) { free(value); luaL_argerror(L, 4, "invalid value"); } data_float[i] = value[0]; data_float[i+1] = value[1]; free(value); lua_pop(L, 1); } } break; case IM_DOUBLE: { double *d = (double*) data; for (i = 0; i < count; i++) { lua_rawgeti(L, 4, i+1); d[i] = (double)luaL_checknumber(L, -1); lua_pop(L, 1); } } break; case IM_CDOUBLE: { double *data_double = (double*) data; for (i = 0; i < count; i++) { int two; double *value = imlua_toarraydouble(L, -1, &two, 1); if (two != 2) { free(value); luaL_argerror(L, 4, "invalid value"); } data_double[i] = value[0]; data_double[i+1] = value[1]; free(value); lua_pop(L, 1); } } break; } } imFileSetAttribute(ifile, attrib, data_type, count, data); return 0; }
int imSaveRGB(int width, int height, int format, unsigned char *red, unsigned char *green, unsigned char *blue, char *filename) { int error; char* new_format = i_format_old2new[format & 0x00FF]; imFile* ifile = imFileNew(filename, new_format, &error); if (!ifile) return error; if (format & 0xFF00) imFileSetInfo(ifile, NULL); else imFileSetInfo(ifile, "NONE"); if (iOldResolutionCB) { double xres, yres; int res_unit; iOldResolutionCB(filename, &xres, &yres, &res_unit); float fxres=(float)xres, fyres=(float)yres; imFileSetAttribute(ifile, "XResolution", IM_FLOAT, 1, (void*)&fxres); imFileSetAttribute(ifile, "YResolution", IM_FLOAT, 1, (void*)&fyres); imFileSetAttribute(ifile, "ResolutionUnit", IM_INT, 1, (void*)&res_unit); } if (iOldTiffImageDescCB) { char img_desc[50]; iOldTiffImageDescCB(filename, img_desc); imFileSetAttribute(ifile, "Description", IM_BYTE, -1, (void*)img_desc); } if (iOldGifTranspIndexCB) { unsigned char transp_index; iOldGifTranspIndexCB(filename, &transp_index); imFileSetAttribute(ifile, "TransparencyIndex", IM_BYTE, 1, (void*)&transp_index); } error = imFileWriteImageInfo(ifile, width, height, IM_RGB, IM_BYTE); if (error) { imFileClose(ifile); return error; } if (iOldCounterCB) imCounterSetCallback(filename, iOldFileCounter); int count = width*height; void* data; if (green != red + count || blue != green + count) data = malloc(imImageDataSize(width, height, IM_RGB, IM_BYTE)); else data = red; if (!data) { imFileClose(ifile); return IM_ERR_MEM; } if (data != red) { memcpy(data, red, count); memcpy((unsigned char*)data+count, green, count); memcpy((unsigned char*)data+2*count, blue, count); } error = imFileWriteImageData(ifile, data); imFileClose(ifile); if (data != red) free(data); return error; }