/src/FreeImage/Source/FreeImage/PluginKOALA.cpp

https://bitbucket.org/cabalistic/ogredeps/ · C++ · 243 lines · 150 code · 51 blank · 42 comment · 12 complexity · f4a026477e927e3534250510fbbfae4b MD5 · raw file

  1. // ==========================================================
  2. // KOALA 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 tagKOALA {
  32. BYTE image[8000]; // pixmap image
  33. BYTE colour1[1000]; // first colourmap (colour 1 and 2)
  34. BYTE colour2[1000]; // second colourmap (colour 3)
  35. BYTE background; // background colour
  36. } koala_t;
  37. struct colour_t {
  38. int r;
  39. int g;
  40. int b;
  41. };
  42. #ifdef _WIN32
  43. #pragma pack(pop)
  44. #else
  45. #pragma pack()
  46. #endif
  47. // ----------------------------------------------------------
  48. #define CBM_WIDTH 320
  49. #define CBM_HEIGHT 200
  50. // ----------------------------------------------------------
  51. const colour_t c64colours[16] = {
  52. { 0, 0, 0 }, // Black
  53. { 255, 255, 255 }, // White
  54. { 170, 17, 17 }, // Red
  55. { 12, 204, 204 }, // Cyan
  56. { 221, 51, 221 }, // Purple
  57. { 0, 187, 0 }, // Green
  58. { 0, 0, 204 }, // Blue
  59. { 255, 255, 140 }, // Yellow
  60. { 204, 119, 34 }, // Orange
  61. { 136, 68, 0 }, // Brown
  62. { 255, 153, 136 }, // Light red
  63. { 92, 92, 92 }, // Gray 1
  64. { 170, 170, 170 }, // Gray 2
  65. { 140, 255, 178 }, // Light green
  66. { 39, 148, 255 }, // Light blue
  67. { 196, 196, 196 } // Gray 3
  68. };
  69. // ==========================================================
  70. // Plugin Interface
  71. // ==========================================================
  72. static int s_format_id;
  73. // ==========================================================
  74. // Plugin Implementation
  75. // ==========================================================
  76. const char * DLL_CALLCONV
  77. Format() {
  78. return "KOALA";
  79. }
  80. const char * DLL_CALLCONV
  81. Description() {
  82. return "C64 Koala Graphics";
  83. }
  84. const char * DLL_CALLCONV
  85. Extension() {
  86. return "koa";
  87. }
  88. const char * DLL_CALLCONV
  89. RegExpr() {
  90. return NULL;
  91. }
  92. static const char * DLL_CALLCONV
  93. MimeType() {
  94. return "image/x-koala";
  95. }
  96. static BOOL DLL_CALLCONV
  97. Validate(FreeImageIO *io, fi_handle handle) {
  98. BYTE koala_signature[] = { 0x00, 0x60 };
  99. BYTE signature[2] = { 0, 0 };
  100. io->read_proc(signature, 1, sizeof(koala_signature), handle);
  101. return (memcmp(koala_signature, signature, sizeof(koala_signature)) == 0);
  102. }
  103. static BOOL DLL_CALLCONV
  104. SupportsExportDepth(int depth) {
  105. return FALSE;
  106. }
  107. static BOOL DLL_CALLCONV
  108. SupportsExportType(FREE_IMAGE_TYPE type) {
  109. return FALSE;
  110. }
  111. // ----------------------------------------------------------
  112. FIBITMAP * DLL_CALLCONV
  113. Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
  114. if (handle) {
  115. koala_t image;
  116. // read the load address
  117. unsigned char load_address[2]; // highbit, lowbit
  118. io->read_proc(&load_address, 1, 2, handle);
  119. // if the load address is correct, skip it. otherwise ignore the load address
  120. if ((load_address[0] != 0x00) || (load_address[1] != 0x60)) {
  121. ((BYTE *)&image)[0] = load_address[0];
  122. ((BYTE *)&image)[1] = load_address[1];
  123. io->read_proc((BYTE *)&image + 2, 1, 10001 - 2, handle);
  124. } else {
  125. io->read_proc(&image, 1, 10001, handle);
  126. }
  127. // build DIB in memory
  128. FIBITMAP *dib = FreeImage_Allocate(CBM_WIDTH, CBM_HEIGHT, 4);
  129. if (dib) {
  130. // write out the commodore 64 color palette
  131. RGBQUAD *palette = FreeImage_GetPalette(dib);
  132. for (int i = 0; i < 16; i++) {
  133. palette[i].rgbBlue = (BYTE)c64colours[i].b;
  134. palette[i].rgbGreen = (BYTE)c64colours[i].g;
  135. palette[i].rgbRed = (BYTE)c64colours[i].r;
  136. }
  137. // write out bitmap data
  138. BYTE pixel_mask[4] = { 0xc0, 0x30, 0x0c, 0x03 };
  139. BYTE pixel_displacement[4] = { 6, 4, 2, 0 };
  140. int pixel, index, colourindex;
  141. unsigned char found_color = 0;
  142. for (int y = 0; y < 200; y++) {
  143. for (int x = 0; x < 160; x++) {
  144. // Get value of pixel at (x,y)
  145. index = (x / 4) * 8 + (y % 8) + (y / 8) * CBM_WIDTH;
  146. colourindex = (x / 4) + (y / 8) * 40;
  147. pixel = (image.image[index] & pixel_mask[x % 4]) >> pixel_displacement[x % 4];
  148. // Retrieve RGB values
  149. switch (pixel) {
  150. case 0: // Background
  151. found_color = image.background;
  152. break;
  153. case 1: // Colour 1
  154. found_color = image.colour1[colourindex] >> 4;
  155. break;
  156. case 2: // Colour 2
  157. found_color = image.colour1[colourindex] & 0xf;
  158. break;
  159. case 3: // Colour 3
  160. found_color = image.colour2[colourindex] & 0xf;
  161. break;
  162. };
  163. *(FreeImage_GetScanLine(dib, CBM_HEIGHT - y - 1) + x) = (found_color << 4) | found_color;
  164. }
  165. }
  166. return dib;
  167. }
  168. }
  169. return NULL;
  170. }
  171. // ==========================================================
  172. // Init
  173. // ==========================================================
  174. void DLL_CALLCONV
  175. InitKOALA(Plugin *plugin, int format_id) {
  176. s_format_id = format_id;
  177. plugin->format_proc = Format;
  178. plugin->description_proc = Description;
  179. plugin->extension_proc = Extension;
  180. plugin->regexpr_proc = RegExpr;
  181. plugin->open_proc = NULL;
  182. plugin->close_proc = NULL;
  183. plugin->pagecount_proc = NULL;
  184. plugin->pagecapability_proc = NULL;
  185. plugin->load_proc = Load;
  186. plugin->save_proc = NULL;
  187. plugin->validate_proc = Validate;
  188. plugin->mime_proc = MimeType;
  189. plugin->supports_export_bpp_proc = SupportsExportDepth;
  190. plugin->supports_export_type_proc = SupportsExportType;
  191. plugin->supports_icc_profiles_proc = NULL;
  192. }