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 /im/src/im_format_raw.cpp |
Initial import. Contains the im, cd and iup librairies, and a "working" Makefile for them under linux.
Diffstat (limited to 'im/src/im_format_raw.cpp')
-rwxr-xr-x | im/src/im_format_raw.cpp | 366 |
1 files changed, 366 insertions, 0 deletions
diff --git a/im/src/im_format_raw.cpp b/im/src/im_format_raw.cpp new file mode 100755 index 0000000..56a2096 --- /dev/null +++ b/im/src/im_format_raw.cpp @@ -0,0 +1,366 @@ +/** \file + * \brief RAW File Format + * + * See Copyright Notice in im_lib.h + * $Id: im_format_raw.cpp,v 1.5 2009/10/01 14:15:47 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[2] = +{ + "NONE", + "ASCII" +}; + +class imFileFormatRAW: public imFileFormatBase +{ + imBinFile* handle; + int padding; + + int iRawUpdateParam(int index); + +public: + imFileFormatRAW(const imFormat* _iformat): imFileFormatBase(_iformat) {} + ~imFileFormatRAW() {} + + 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); +}; + +class imFormatRAW: public imFormat +{ +public: + imFormatRAW() + :imFormat("RAW", + "RAW File Format", + "*.*;", + iRAWCompTable, + 2, + 1) + {} + ~imFormatRAW() {} + + imFileFormatBase* Create(void) const { return new imFileFormatRAW(this); } + int CanWrite(const char* compression, int color_mode, int data_type) const; +}; + +static imFormat* raw_format = NULL; + +void imFormatFinishRAW(void) +{ + if (raw_format) + { + delete raw_format; + raw_format = NULL; + } +} + +imFormat* imFormatInitRAW(void) +{ + if (!raw_format) + raw_format = new imFormatRAW(); + + return raw_format; +} + +int imFileFormatRAW::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 = 1; /* at least one image */ + this->padding = 0; + + return IM_ERR_NONE; +} + +int imFileFormatRAW::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 imFileFormatRAW::Close() +{ + imBinFileClose(this->handle); +} + +void* imFileFormatRAW::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 imFileFormatRAW::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 imFileFormatRAW::ReadImageInfo(int index) +{ + return iRawUpdateParam(index); +} + +int imFileFormatRAW::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 imFileFormatRAW::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; + } + + int ascii; + if (imStrEqual(this->compression, "ASCII")) + ascii = 1; + else + ascii = 0; + + imCounterTotal(this->counter, count, "Reading RAW..."); + + int row = 0, plane = 0; + for (int i = 0; i < count; i++) + { + if (ascii) + { + for (int col = 0; col < line_count; col++) + { + if (this->file_data_type == IM_FLOAT) + { + float value; + if (!imBinFileReadFloat(handle, &value)) + return IM_ERR_ACCESS; + + ((float*)this->line_buffer)[col] = value; + } + else + { + int value; + if (!imBinFileReadInteger(handle, &value)) + return IM_ERR_ACCESS; + + if (this->file_data_type == IM_INT) + ((int*)this->line_buffer)[col] = value; + else if (this->file_data_type == IM_USHORT) + ((imushort*)this->line_buffer)[col] = (imushort)value; + else + ((imbyte*)this->line_buffer)[col] = (unsigned char)value; + } + } + } + else + { + 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 imFileFormatRAW::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; + } + + int ascii; + if (imStrEqual(this->compression, "ASCII")) + ascii = 1; + else + ascii = 0; + + imCounterTotal(this->counter, count, "Writing RAW..."); + + int row = 0, plane = 0; + for (int i = 0; i < count; i++) + { + imFileLineBufferWrite(this, data, row, plane); + + if (ascii) + { + for (int col = 0; col < line_count; col++) + { + if (this->file_data_type == IM_FLOAT) + { + float value = ((float*)this->line_buffer)[col]; + + if (!imBinFilePrintf(handle, "%f ", (double)value)) + return IM_ERR_ACCESS; + } + else + { + int value; + if (this->file_data_type == IM_INT) + value = ((int*)this->line_buffer)[col]; + else if (this->file_data_type == IM_USHORT) + value = ((imushort*)this->line_buffer)[col]; + else + value = ((imbyte*)this->line_buffer)[col]; + + if (!imBinFilePrintf(handle, "%d ", value)) + return IM_ERR_ACCESS; + } + } + + imBinFileWrite(handle, (void*)"\n", 1, 1); + } + else + { + 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") && !imStrEqual(compression, "ASCII")) + return IM_ERR_COMPRESS; + + return IM_ERR_NONE; +} |