PageRenderTime 15ms CodeModel.GetById 1ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/src/FreeImage/Source/FreeImage/PluginCUT.cpp

https://bitbucket.org/cabalistic/ogredeps/
C++ | 240 lines | 151 code | 50 blank | 39 comment | 28 complexity | cafb02db2dfdb001b0e775b93b2ac552 MD5 | raw file
  1// ==========================================================
  2// CUT Loader
  3//
  4// Design and implementation by
  5// - Floris van den Berg (flvdberg@wxs.nl)
  6//
  7// This file is part of FreeImage 3
  8//
  9// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
 10// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
 11// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
 12// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
 13// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
 14// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
 15// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
 16// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
 17// THIS DISCLAIMER.
 18//
 19// Use at your own risk!
 20// ==========================================================
 21
 22#include "FreeImage.h"
 23#include "Utilities.h"
 24
 25// ----------------------------------------------------------
 26//   Constants + headers
 27// ----------------------------------------------------------
 28
 29#ifdef _WIN32
 30#pragma pack(push, 1)
 31#else
 32#pragma pack(1)
 33#endif
 34
 35typedef struct tagCUTHEADER {
 36	WORD width;
 37	WORD height;
 38	LONG dummy;
 39} CUTHEADER;
 40
 41#ifdef _WIN32
 42#pragma pack(pop)
 43#else
 44#pragma pack()
 45#endif
 46
 47// ==========================================================
 48// Plugin Interface
 49// ==========================================================
 50
 51static int s_format_id;
 52
 53// ==========================================================
 54// Plugin Implementation
 55// ==========================================================
 56
 57static const char * DLL_CALLCONV
 58Format() {
 59	return "CUT";
 60}
 61
 62static const char * DLL_CALLCONV
 63Description() {
 64	return "Dr. Halo";
 65}
 66
 67static const char * DLL_CALLCONV
 68Extension() {
 69	return "cut";
 70}
 71
 72static const char * DLL_CALLCONV
 73RegExpr() {
 74	return NULL;
 75}
 76
 77static const char * DLL_CALLCONV
 78MimeType() {
 79	return "image/x-cut";
 80}
 81
 82static BOOL DLL_CALLCONV
 83Validate(FreeImageIO *io, fi_handle handle) {
 84	return FALSE;
 85}
 86
 87static BOOL DLL_CALLCONV
 88SupportsExportDepth(int depth) {
 89	return FALSE;
 90}
 91
 92static BOOL DLL_CALLCONV 
 93SupportsExportType(FREE_IMAGE_TYPE type) {
 94	return FALSE;
 95}
 96
 97static BOOL DLL_CALLCONV
 98SupportsNoPixels() {
 99	return TRUE;
100}
101
102// ----------------------------------------------------------
103
104static FIBITMAP * DLL_CALLCONV
105Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
106	FIBITMAP *dib = NULL;
107
108	if(!handle) {
109		return NULL;
110	}
111
112	try {
113		CUTHEADER header;		
114
115		BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
116
117		// read the cut header
118
119		if(io->read_proc(&header, 1, sizeof(CUTHEADER), handle) != sizeof(CUTHEADER)) {
120			throw FI_MSG_ERROR_PARSING;
121		}
122
123#ifdef FREEIMAGE_BIGENDIAN
124		SwapShort((WORD *)&header.width);
125		SwapShort((WORD *)&header.height);
126#endif
127
128		if ((header.width == 0) || (header.height == 0)) {
129			return NULL;
130		}
131
132		// allocate a new bitmap
133
134		dib = FreeImage_AllocateHeader(header_only, header.width, header.height, 8);
135
136		if (dib == NULL) {
137			throw FI_MSG_ERROR_DIB_MEMORY;
138		}
139
140		// stuff it with a palette
141
142		RGBQUAD *palette = FreeImage_GetPalette(dib);
143
144		for (int j = 0; j < 256; ++j) {
145			palette[j].rgbBlue = palette[j].rgbGreen = palette[j].rgbRed = (BYTE)j;
146		}
147		
148		if(header_only) {
149			// header only mode
150			return dib;
151		}
152
153		// unpack the RLE bitmap bits
154
155		BYTE *bits = FreeImage_GetScanLine(dib, header.height - 1);
156
157		unsigned i = 0, k = 0;
158		unsigned pitch = FreeImage_GetPitch(dib);
159		unsigned size = header.width * header.height;
160		BYTE count = 0, run = 0;
161
162		while (i < size) {
163			if(io->read_proc(&count, 1, sizeof(BYTE), handle) != 1) {
164				throw FI_MSG_ERROR_PARSING;
165			}
166
167			if (count == 0) {
168				k = 0;
169				bits -= pitch;
170
171				// paint shop pro adds two useless bytes here...
172
173				io->read_proc(&count, 1, sizeof(BYTE), handle);
174				io->read_proc(&count, 1, sizeof(BYTE), handle);
175
176				continue;
177			}
178
179			if (count & 0x80) {
180				count &= ~(0x80);
181
182				if(io->read_proc(&run, 1, sizeof(BYTE), handle) != 1) {
183					throw FI_MSG_ERROR_PARSING;
184				}
185
186				if(k + count <= header.width) {
187					memset(bits + k, run, count);
188				} else {
189					throw FI_MSG_ERROR_PARSING;
190				}
191			} else {
192				if(k + count <= header.width) {
193					if(io->read_proc(&bits[k], count, sizeof(BYTE), handle) != 1) {
194						throw FI_MSG_ERROR_PARSING;
195					}
196				} else {
197					throw FI_MSG_ERROR_PARSING;
198				}
199			}
200
201			k += count;
202			i += count;
203		}
204
205		return dib;
206
207	} catch(const char* text) {
208		if(dib) {
209			FreeImage_Unload(dib);
210		}
211		FreeImage_OutputMessageProc(s_format_id, text);
212		return NULL;
213	}
214}
215
216// ==========================================================
217//   Init
218// ==========================================================
219
220void DLL_CALLCONV
221InitCUT(Plugin *plugin, int format_id) {
222	s_format_id = format_id;
223
224	plugin->format_proc = Format;
225	plugin->description_proc = Description;
226	plugin->extension_proc = Extension;
227	plugin->regexpr_proc = RegExpr;
228	plugin->open_proc = NULL;
229	plugin->close_proc = NULL;
230	plugin->pagecount_proc = NULL;
231	plugin->pagecapability_proc = NULL;
232	plugin->load_proc = Load;
233	plugin->save_proc = NULL;
234	plugin->validate_proc = Validate;
235	plugin->mime_proc = MimeType;
236	plugin->supports_export_bpp_proc = SupportsExportDepth;
237	plugin->supports_export_type_proc = SupportsExportType;
238	plugin->supports_icc_profiles_proc = NULL;
239	plugin->supports_no_pixels_proc = SupportsNoPixels;
240}