summaryrefslogtreecommitdiff
path: root/src/im_file.cpp
diff options
context:
space:
mode:
authorscuri <scuri>2008-10-17 06:10:15 +0000
committerscuri <scuri>2008-10-17 06:10:15 +0000
commit5a422aba704c375a307a902bafe658342e209906 (patch)
tree5005011e086bb863d8fb587ad3319bbec59b2447 /src/im_file.cpp
First commit - moving from LuaForge to SourceForge
Diffstat (limited to 'src/im_file.cpp')
-rw-r--r--src/im_file.cpp428
1 files changed, 428 insertions, 0 deletions
diff --git a/src/im_file.cpp b/src/im_file.cpp
new file mode 100644
index 0000000..81e6128
--- /dev/null
+++ b/src/im_file.cpp
@@ -0,0 +1,428 @@
+/** \file
+ * \brief File Access
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: im_file.cpp,v 1.1 2008/10/17 06:10:16 scuri Exp $
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "im.h"
+#include "im_format.h"
+#include "im_util.h"
+#include "im_attrib.h"
+#include "im_counter.h"
+#include "im_plus.h" // make shure that this file is compiled
+
+
+void imFileClear(imFile* ifile)
+{
+ // can not reset compression and image_count
+
+ ifile->is_new = 0;
+ ifile->attrib_table = 0;
+
+ ifile->line_buffer = 0;
+ ifile->line_buffer_size = 0;
+ ifile->line_buffer_extra = 0;
+ ifile->line_buffer_alloc = 0;
+
+ ifile->convert_bpp = 0;
+ ifile->switch_type = 0;
+
+ ifile->width = 0;
+ ifile->height = 0;
+ ifile->image_index = -1;
+ ifile->user_data_type = 0;
+ ifile->user_color_mode = 0;
+ ifile->file_data_type = 0;
+ ifile->file_color_mode = 0;
+
+ ifile->palette_count = 256;
+ for (int i = 0; i < 256; i++)
+ ifile->palette[i] = imColorEncode((imbyte)i, (imbyte)i, (imbyte)i);
+}
+
+imFile* imFileOpen(const char* file_name, int *error)
+{
+ assert(file_name);
+
+ imFormat* iformat = imFormatOpen(file_name, error);
+ if (!iformat)
+ return NULL;
+
+ imFileClear(iformat);
+
+ iformat->attrib_table = new imAttribTable(599);
+
+ iformat->counter = imCounterBegin(file_name);
+
+ return iformat;
+}
+
+imFile* imFileOpenAs(const char* file_name, const char* format, int *error)
+{
+ assert(file_name);
+
+ imFormat* iformat = imFormatOpenAs(file_name, format, error);
+ if (!iformat)
+ return NULL;
+
+ imFileClear(iformat);
+
+ iformat->attrib_table = new imAttribTable(599);
+
+ iformat->counter = imCounterBegin(file_name);
+
+ return iformat;
+}
+
+imFile* imFileNew(const char* file_name, const char* format, int *error)
+{
+ assert(file_name);
+
+ imFormat* iformat = imFormatNew(file_name, format, error);
+ if (!iformat)
+ return NULL;
+
+ imFileClear(iformat);
+
+ iformat->is_new = 1;
+ iformat->image_count = 0;
+ iformat->compression[0] = 0;
+
+ iformat->attrib_table = new imAttribTable(101);
+
+ iformat->counter = imCounterBegin(file_name);
+
+ return iformat;
+}
+
+void imFileClose(imFile* ifile)
+{
+ assert(ifile);
+ imFormat* iformat = (imFormat*)ifile;
+ imAttribTable* attrib_table = (imAttribTable*)ifile->attrib_table;
+
+ imCounterEnd(ifile->counter);
+
+ iformat->Close();
+
+ if (ifile->line_buffer) free(ifile->line_buffer);
+
+ delete attrib_table;
+}
+
+void* imFileHandle(imFile* ifile, int index)
+{
+ assert(ifile);
+ imFormat* iformat = (imFormat*)ifile;
+ return iformat->Handle(index);
+}
+
+void imFileSetAttribute(imFile* ifile, const char* attrib, int data_type, int count, const void* data)
+{
+ assert(ifile);
+ assert(attrib);
+ imFormat* iformat = (imFormat*)ifile;
+ imAttribTable* atable = (imAttribTable*)iformat->attrib_table;
+ if (data)
+ atable->Set(attrib, data_type, count, data);
+ else
+ atable->UnSet(attrib);
+}
+
+const void* imFileGetAttribute(imFile* ifile, const char* attrib, int *data_type, int *count)
+{
+ assert(ifile);
+ assert(attrib);
+ imFormat* iformat = (imFormat*)ifile;
+ imAttribTable* attrib_table = (imAttribTable*)iformat->attrib_table;
+ return attrib_table->Get(attrib, data_type, count);
+}
+
+static int iAttribCB(void* user_data, int index, const char* name, int data_type, int count, const void* data)
+{
+ (void)data_type;
+ (void)data;
+ (void)count;
+ char** attrib = (char**)user_data;
+ attrib[index] = (char*)name;
+ return 1;
+}
+
+void imFileGetAttributeList(imFile* ifile, char** attrib, int *attrib_count)
+{
+ assert(ifile);
+ assert(attrib_count);
+
+ imAttribTable* attrib_table = (imAttribTable*)ifile->attrib_table;
+ *attrib_count = attrib_table->Count();
+
+ if (attrib) attrib_table->ForEach((void*)attrib, iAttribCB);
+}
+
+void imFileGetInfo(imFile* ifile, char* format, char* compression, int *image_count)
+{
+ assert(ifile);
+ imFormat* iformat = (imFormat*)ifile;
+
+ if(compression) strcpy(compression, ifile->compression);
+ if(format) strcpy(format, iformat->format);
+ if (image_count) *image_count = ifile->image_count;
+}
+
+static int iFileCheckPaletteGray(imFile* ifile)
+{
+ imbyte r, g, b;
+ for (int i = 0; i < ifile->palette_count; i++)
+ {
+ imColorDecode(&r, &g, &b, ifile->palette[i]);
+
+ if (i != r || r != g || g != b)
+ return 0;
+ }
+
+ return 1;
+}
+
+static int iFileCheckPaletteBinary(imFile* ifile)
+{
+ if (ifile->palette_count > 2)
+ return 0;
+
+ imbyte r, g, b;
+
+ imColorDecode(&r, &g, &b, ifile->palette[0]);
+ if ((r != 0 || g != 0 || b != 0) &&
+ (r != 1 || g != 1 || b != 1) &&
+ (r != 255 || g != 255 || b != 255))
+ return 0;
+
+ imColorDecode(&r, &g, &b, ifile->palette[1]);
+ if ((r != 0 || g != 0 || b != 0) &&
+ (r != 1 || g != 1 || b != 1) &&
+ (r != 255 || g != 255 || b != 255))
+ return 0;
+
+ return 1;
+}
+
+int imFileReadImageInfo(imFile* ifile, int index, int *width, int *height, int *file_color_mode, int *file_data_type)
+{
+ assert(ifile);
+ assert(!ifile->is_new);
+ imFormat* iformat = (imFormat*)ifile;
+
+ if (index >= ifile->image_count)
+ return IM_ERR_DATA;
+
+ if (ifile->image_index != -1 &&
+ ifile->image_index == index)
+ {
+ if(width) *width = ifile->width;
+ if(height) *height = ifile->height;
+ if(file_color_mode) *file_color_mode = ifile->file_color_mode;
+ if(file_data_type) *file_data_type = ifile->file_data_type;
+
+ return IM_ERR_NONE;
+ }
+
+ ifile->convert_bpp = 0;
+ ifile->switch_type = 0;
+
+ int error = iformat->ReadImageInfo(index);
+ if (error) return error;
+
+ if (!imImageCheckFormat(ifile->file_color_mode, ifile->file_data_type))
+ return IM_ERR_DATA;
+
+ if (imColorModeSpace(ifile->file_color_mode) == IM_BINARY)
+ {
+ ifile->palette_count = 2;
+ ifile->palette[0] = imColorEncode(0, 0, 0);
+ ifile->palette[1] = imColorEncode(255, 255, 255);
+ }
+
+ if (imColorModeSpace(ifile->file_color_mode) == IM_MAP)
+ {
+ if (iFileCheckPaletteGray(ifile))
+ ifile->file_color_mode = (ifile->file_color_mode & 0xFF00) | IM_GRAY;
+
+ if (iFileCheckPaletteBinary(ifile))
+ ifile->file_color_mode = (ifile->file_color_mode & 0xFF00) | IM_BINARY;
+ }
+
+ if(width) *width = ifile->width;
+ if(height) *height = ifile->height;
+ if(file_color_mode) *file_color_mode = ifile->file_color_mode;
+ if(file_data_type) *file_data_type = ifile->file_data_type;
+
+ ifile->image_index = index;
+
+ return IM_ERR_NONE;
+}
+
+void imFileGetPalette(imFile* ifile, long* palette, int *palette_count)
+{
+ assert(ifile);
+ assert(palette);
+
+ if (ifile->palette_count != 0 && palette)
+ memcpy(palette, ifile->palette, ifile->palette_count*sizeof(long));
+
+ if (palette_count) *palette_count = ifile->palette_count;
+}
+
+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++;
+ }
+}
+
+static void iFileCheckConvertBinary(imFile* ifile, imbyte* data)
+{
+ int count = ifile->width*ifile->height;
+ for(int i = 0; i < count; i++)
+ {
+ if (*data)
+ *data = 1;
+ data++;
+ }
+}
+
+int imFileReadImageData(imFile* ifile, void* data, int convert2bitmap, int color_mode_flags)
+{
+ assert(ifile);
+ assert(!ifile->is_new);
+ imFormat* iformat = (imFormat*)ifile;
+
+ if (ifile->image_index == -1)
+ return IM_ERR_DATA;
+
+ ifile->user_color_mode = ifile->file_color_mode;
+ ifile->user_data_type = ifile->file_data_type;
+
+ if (convert2bitmap)
+ {
+ ifile->user_data_type = IM_BYTE;
+ ifile->user_color_mode = imColorModeToBitmap(ifile->file_color_mode);
+ }
+
+ if (color_mode_flags != -1)
+ {
+ ifile->user_color_mode = imColorModeSpace(ifile->user_color_mode);
+ ifile->user_color_mode |= color_mode_flags;
+ }
+
+ if (!imImageCheckFormat(ifile->user_color_mode, ifile->user_data_type))
+ return IM_ERR_DATA;
+
+ if (!imFileCheckConversion(ifile))
+ return IM_ERR_DATA;
+
+ imFileLineBufferInit(ifile);
+
+ int ret = iformat->ReadImageData(data);
+
+ // here we can NOT change the file_color_mode we already returned to the user
+ // so just check for gray and binary consistency
+
+ if (imColorModeSpace(ifile->file_color_mode) == IM_GRAY && ifile->file_data_type == IM_BYTE)
+ iFileCheckConvertGray(ifile, (imbyte*)data);
+
+ if (imColorModeSpace(ifile->file_color_mode) == IM_BINARY)
+ iFileCheckConvertBinary(ifile, (imbyte*)data);
+
+ return ret;
+}
+
+void imFileSetInfo(imFile* ifile, const char* compression)
+{
+ assert(ifile);
+ assert(ifile->is_new);
+
+ if (!compression)
+ ifile->compression[0] = 0;
+ else
+ strcpy(ifile->compression, compression);
+}
+
+void imFileSetPalette(imFile* ifile, long* palette, int palette_count)
+{
+ assert(ifile);
+ assert(palette);
+ assert(palette_count != 0);
+
+ memcpy(ifile->palette, palette, palette_count*sizeof(long));
+ ifile->palette_count = palette_count;
+}
+
+int imFileWriteImageInfo(imFile* ifile, int width, int height, int user_color_mode, int user_data_type)
+{
+ assert(ifile);
+ assert(ifile->is_new);
+ imFormat* iformat = (imFormat*)ifile;
+
+ if (!imImageCheckFormat(user_color_mode, user_data_type))
+ return IM_ERR_DATA;
+
+ int error = iformat->CanWrite(ifile->compression, user_color_mode, user_data_type);
+ if (error) return error;
+
+ ifile->width = width;
+ ifile->height = height;
+ ifile->user_color_mode = user_color_mode;
+ ifile->user_data_type = user_data_type;
+
+ if (imColorModeSpace(user_color_mode) == IM_BINARY)
+ {
+ ifile->palette_count = 2;
+ ifile->palette[0] = imColorEncode(0, 0, 0);
+ ifile->palette[1] = imColorEncode(255, 255, 255);
+ }
+
+ return iformat->WriteImageInfo();
+}
+
+int imFileWriteImageData(imFile* ifile, void* data)
+{
+ assert(ifile);
+ assert(ifile->is_new);
+ assert(data);
+ imFormat* iformat = (imFormat*)ifile;
+
+ if (!imFileCheckConversion(ifile))
+ return IM_ERR_DATA;
+
+ imFileLineBufferInit(ifile);
+
+ return iformat->WriteImageData(data);
+}