/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. #include "FreeImage.h"
  22. #include "Utilities.h"
  23. // ----------------------------------------------------------
  24. // Constants + headers
  25. // ----------------------------------------------------------
  26. #ifdef _WIN32
  27. #pragma pack(push, 1)
  28. #else
  29. #pragma pack(1)
  30. #endif
  31. typedef struct tagCUTHEADER {
  32. WORD width;
  33. WORD height;
  34. LONG dummy;
  35. } CUTHEADER;
  36. #ifdef _WIN32
  37. #pragma pack(pop)
  38. #else
  39. #pragma pack()
  40. #endif
  41. // ==========================================================
  42. // Plugin Interface
  43. // ==========================================================
  44. static int s_format_id;
  45. // ==========================================================
  46. // Plugin Implementation
  47. // ==========================================================
  48. static const char * DLL_CALLCONV
  49. Format() {
  50. return "CUT";
  51. }
  52. static const char * DLL_CALLCONV
  53. Description() {
  54. return "Dr. Halo";
  55. }
  56. static const char * DLL_CALLCONV
  57. Extension() {
  58. return "cut";
  59. }
  60. static const char * DLL_CALLCONV
  61. RegExpr() {
  62. return NULL;
  63. }
  64. static const char * DLL_CALLCONV
  65. MimeType() {
  66. return "image/x-cut";
  67. }
  68. static BOOL DLL_CALLCONV
  69. Validate(FreeImageIO *io, fi_handle handle) {
  70. return FALSE;
  71. }
  72. static BOOL DLL_CALLCONV
  73. SupportsExportDepth(int depth) {
  74. return FALSE;
  75. }
  76. static BOOL DLL_CALLCONV
  77. SupportsExportType(FREE_IMAGE_TYPE type) {
  78. return FALSE;
  79. }
  80. static BOOL DLL_CALLCONV
  81. SupportsNoPixels() {
  82. return TRUE;
  83. }
  84. // ----------------------------------------------------------
  85. static FIBITMAP * DLL_CALLCONV
  86. Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
  87. FIBITMAP *dib = NULL;
  88. if(!handle) {
  89. return NULL;
  90. }
  91. try {
  92. CUTHEADER header;
  93. BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
  94. // read the cut header
  95. if(io->read_proc(&header, 1, sizeof(CUTHEADER), handle) != sizeof(CUTHEADER)) {
  96. throw FI_MSG_ERROR_PARSING;
  97. }
  98. #ifdef FREEIMAGE_BIGENDIAN
  99. SwapShort((WORD *)&header.width);
  100. SwapShort((WORD *)&header.height);
  101. #endif
  102. if ((header.width == 0) || (header.height == 0)) {
  103. return NULL;
  104. }
  105. // allocate a new bitmap
  106. dib = FreeImage_AllocateHeader(header_only, header.width, header.height, 8);
  107. if (dib == NULL) {
  108. throw FI_MSG_ERROR_DIB_MEMORY;
  109. }
  110. // stuff it with a palette
  111. RGBQUAD *palette = FreeImage_GetPalette(dib);
  112. for (int j = 0; j < 256; ++j) {
  113. palette[j].rgbBlue = palette[j].rgbGreen = palette[j].rgbRed = (BYTE)j;
  114. }
  115. if(header_only) {
  116. // header only mode
  117. return dib;
  118. }
  119. // unpack the RLE bitmap bits
  120. BYTE *bits = FreeImage_GetScanLine(dib, header.height - 1);
  121. unsigned i = 0, k = 0;
  122. unsigned pitch = FreeImage_GetPitch(dib);
  123. unsigned size = header.width * header.height;
  124. BYTE count = 0, run = 0;
  125. while (i < size) {
  126. if(io->read_proc(&count, 1, sizeof(BYTE), handle) != 1) {
  127. throw FI_MSG_ERROR_PARSING;
  128. }
  129. if (count == 0) {
  130. k = 0;
  131. bits -= pitch;
  132. // paint shop pro adds two useless bytes here...
  133. io->read_proc(&count, 1, sizeof(BYTE), handle);
  134. io->read_proc(&count, 1, sizeof(BYTE), handle);
  135. continue;
  136. }
  137. if (count & 0x80) {
  138. count &= ~(0x80);
  139. if(io->read_proc(&run, 1, sizeof(BYTE), handle) != 1) {
  140. throw FI_MSG_ERROR_PARSING;
  141. }
  142. if(k + count <= header.width) {
  143. memset(bits + k, run, count);
  144. } else {
  145. throw FI_MSG_ERROR_PARSING;
  146. }
  147. } else {
  148. if(k + count <= header.width) {
  149. if(io->read_proc(&bits[k], count, sizeof(BYTE), handle) != 1) {
  150. throw FI_MSG_ERROR_PARSING;
  151. }
  152. } else {
  153. throw FI_MSG_ERROR_PARSING;
  154. }
  155. }
  156. k += count;
  157. i += count;
  158. }
  159. return dib;
  160. } catch(const char* text) {
  161. if(dib) {
  162. FreeImage_Unload(dib);
  163. }
  164. FreeImage_OutputMessageProc(s_format_id, text);
  165. return NULL;
  166. }
  167. }
  168. // ==========================================================
  169. // Init
  170. // ==========================================================
  171. void DLL_CALLCONV
  172. InitCUT(Plugin *plugin, int format_id) {
  173. s_format_id = format_id;
  174. plugin->format_proc = Format;
  175. plugin->description_proc = Description;
  176. plugin->extension_proc = Extension;
  177. plugin->regexpr_proc = RegExpr;
  178. plugin->open_proc = NULL;
  179. plugin->close_proc = NULL;
  180. plugin->pagecount_proc = NULL;
  181. plugin->pagecapability_proc = NULL;
  182. plugin->load_proc = Load;
  183. plugin->save_proc = NULL;
  184. plugin->validate_proc = Validate;
  185. plugin->mime_proc = MimeType;
  186. plugin->supports_export_bpp_proc = SupportsExportDepth;
  187. plugin->supports_export_type_proc = SupportsExportType;
  188. plugin->supports_icc_profiles_proc = NULL;
  189. plugin->supports_no_pixels_proc = SupportsNoPixels;
  190. }