diff options
author | scuri <scuri> | 2008-10-17 06:10:15 +0000 |
---|---|---|
committer | scuri <scuri> | 2008-10-17 06:10:15 +0000 |
commit | 5a422aba704c375a307a902bafe658342e209906 (patch) | |
tree | 5005011e086bb863d8fb587ad3319bbec59b2447 /src/im_format_raw.cpp |
First commit - moving from LuaForge to SourceForge
Diffstat (limited to 'src/im_format_raw.cpp')
-rw-r--r-- | src/im_format_raw.cpp | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/src/im_format_raw.cpp b/src/im_format_raw.cpp new file mode 100644 index 0000000..83ffadb --- /dev/null +++ b/src/im_format_raw.cpp @@ -0,0 +1,270 @@ +/** \file + * \brief RAW File Format + * + * See Copyright Notice in im_lib.h + * $Id: im_format_raw.cpp,v 1.1 2008/10/17 06:10:16 scuri Exp $ + */ + +#include "im_format.h" +#include "im_util.h" +#include "im_format_raw.h" +#include "im_counter.h" + +#include "im_binfile.h" + +#include <stdlib.h> +#include <string.h> + +static const char* iRAWCompTable[1] = +{ + "NONE" +}; + +class imFormatRAW: public imFormat +{ + imBinFile* handle; + int padding; + + int iRawUpdateParam(int index); + +public: + imFormatRAW() + :imFormat("RAW", + "RAW File Format", + "*.*;", + iRAWCompTable, + 1, + 1) + {} + ~imFormatRAW() {} + + int Open(const char* file_name); + int New(const char* file_name); + void Close(); + void* Handle(int index); + int ReadImageInfo(int index); + int ReadImageData(void* data); + int WriteImageInfo(); + int WriteImageData(void* data); + int CanWrite(const char* compression, int color_mode, int data_type) const; +}; + +imFormat* imFormatInitRAW(void) +{ + return new imFormatRAW(); +} + +int imFormatRAW::Open(const char* file_name) +{ + this->handle = imBinFileOpen(file_name); + if (this->handle == NULL) + return IM_ERR_OPEN; + + strcpy(this->compression, "NONE"); + + this->image_count = 0; + this->padding = 0; + + return IM_ERR_NONE; +} + +int imFormatRAW::New(const char* file_name) +{ + this->handle = imBinFileNew(file_name); + if (this->handle == NULL) + return IM_ERR_OPEN; + + this->padding = 0; + + return IM_ERR_NONE; +} + +void imFormatRAW::Close() +{ + imBinFileClose(this->handle); +} + +void* imFormatRAW::Handle(int index) +{ + if (index == 0) + return (void*)this->handle; + else + return NULL; +} + +static int iCalcPad(int padding, int line_size) +{ + if (padding == 1) + return 0; + + { + int rest = line_size % padding; + if (rest == 0) + return 0; + + return padding - rest; + } +} + +int imFormatRAW::iRawUpdateParam(int index) +{ + (void)index; + + imAttribTable* attrib_table = AttribTable(); + + // update image count + int* icount = (int*)attrib_table->Get("ImageCount"); + if (icount) + this->image_count = *icount; + else + this->image_count = 1; + + // update file byte order + int* byte_order = (int*)attrib_table->Get("ByteOrder"); + if (byte_order) + imBinFileByteOrder(this->handle, *byte_order); + + // position at start offset, the default is at 0 + int* start_offset = (int*)attrib_table->Get("StartOffset"); + if (!start_offset) + imBinFileSeekOffset(this->handle, 0); + else + imBinFileSeekOffset(this->handle, *start_offset); + + if (imBinFileError(this->handle)) + return IM_ERR_ACCESS; + + int* stype = (int*)attrib_table->Get("SwitchType"); + if (stype) + this->switch_type = *stype; + + // The following attributes MUST exist + this->width = *(int*)attrib_table->Get("Width"); + this->height = *(int*)attrib_table->Get("Height"); + this->file_color_mode = *(int*)attrib_table->Get("ColorMode"); + this->file_data_type = *(int*)attrib_table->Get("DataType"); + + int* pad = (int*)attrib_table->Get("Padding"); + if (pad) + { + int line_size = imImageLineSize(this->width, this->file_color_mode, this->file_data_type); + if (this->switch_type && (this->file_data_type == IM_FLOAT || this->file_data_type == IM_CFLOAT)) + line_size *= 2; + this->padding = iCalcPad(*pad, line_size); + } + + return IM_ERR_NONE; +} + +int imFormatRAW::ReadImageInfo(int index) +{ + return iRawUpdateParam(index); +} + +int imFormatRAW::WriteImageInfo() +{ + this->file_color_mode = this->user_color_mode; + this->file_data_type = this->user_data_type; + + return iRawUpdateParam(this->image_count); +} + +static int iFileDataTypeSize(int file_data_type, int switch_type) +{ + int type_size = imDataTypeSize(file_data_type); + if ((file_data_type == IM_FLOAT || file_data_type == IM_CFLOAT) && switch_type) + type_size *= 2; + return type_size; +} + +int imFormatRAW::ReadImageData(void* data) +{ + int count = imFileLineBufferCount(this); + int line_count = imImageLineCount(this->width, this->file_color_mode); + int type_size = iFileDataTypeSize(this->file_data_type, this->switch_type); + + // treat complex as 2 real + if (this->file_data_type == IM_CFLOAT) + { + type_size /= 2; + line_count *= 2; + } + + imCounterTotal(this->counter, count, "Reading RAW..."); + + int row = 0, plane = 0; + for (int i = 0; i < count; i++) + { + imBinFileRead(this->handle, (imbyte*)this->line_buffer, line_count, type_size); + + if (imBinFileError(this->handle)) + return IM_ERR_ACCESS; + + imFileLineBufferRead(this, data, row, plane); + + if (!imCounterInc(this->counter)) + return IM_ERR_COUNTER; + + imFileLineBufferInc(this, &row, &plane); + + if (this->padding) + imBinFileSeekOffset(this->handle, this->padding); + } + + return IM_ERR_NONE; +} + +int imFormatRAW::WriteImageData(void* data) +{ + int count = imFileLineBufferCount(this); + int line_count = imImageLineCount(this->width, this->file_color_mode); + int type_size = iFileDataTypeSize(this->file_data_type, this->switch_type); + + // treat complex as 2 real + if (this->file_data_type == IM_CFLOAT) + { + type_size /= 2; + line_count *= 2; + } + + imCounterTotal(this->counter, count, "Writing RAW..."); + + int row = 0, plane = 0; + for (int i = 0; i < count; i++) + { + imFileLineBufferWrite(this, data, row, plane); + + imBinFileWrite(this->handle, (imbyte*)this->line_buffer, line_count, type_size); + + if (imBinFileError(this->handle)) + return IM_ERR_ACCESS; + + if (!imCounterInc(this->counter)) + return IM_ERR_COUNTER; + + imFileLineBufferInc(this, &row, &plane); + + if (this->padding) + imBinFileSeekOffset(this->handle, this->padding); + } + + this->image_count++; + return IM_ERR_NONE; +} + +int imFormatRAW::CanWrite(const char* compression, int color_mode, int data_type) const +{ + (void)data_type; + + if (imColorSpace(color_mode) == IM_MAP) + return IM_ERR_DATA; + + if (!compression || compression[0] == 0) + return IM_ERR_NONE; + + if (!imStrEqual(compression, "NONE")) + return IM_ERR_COMPRESS; + + return IM_ERR_NONE; +} + |