Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

283 lines
5.8 KiB

  1. //
  2. // mxToolKit (c) 1999 by Mete Ciragan
  3. //
  4. // file: mxBmp.cpp
  5. // implementation: all
  6. // last modified: Apr 15 1999, Mete Ciragan
  7. // copyright: The programs and associated files contained in this
  8. // distribution were developed by Mete Ciragan. The programs
  9. // are not in the public domain, but they are freely
  10. // distributable without licensing fees. These programs are
  11. // provided without guarantee or warrantee expressed or
  12. // implied.
  13. // lbmlib.c
  14. #include "mxtk/mxBmp.h"
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. mxImage *
  19. mxBmpRead (const char *filename)
  20. {
  21. int i;
  22. FILE *pfile = 0;
  23. mxBitmapFileHeader bmfh;
  24. mxBitmapInfoHeader bmih;
  25. mxBitmapRGBQuad rgrgbPalette[256];
  26. int cbBmpBits;
  27. byte *pbBmpBits;
  28. byte *pb, *pbPal = 0;
  29. int cbPalBytes;
  30. int biTrueWidth;
  31. mxImage *image = 0;
  32. bool success = false;
  33. // File exists?
  34. if ((pfile = fopen (filename, "rb")) == 0)
  35. return 0;
  36. // Read file header
  37. if (fread (&bmfh, sizeof bmfh, 1/*count*/, pfile) != 1)
  38. goto GetOut;
  39. // Bogus file header check
  40. if (!(bmfh.bfReserved1 == 0 && bmfh.bfReserved2 == 0))
  41. goto GetOut;
  42. // Read info header
  43. if (fread (&bmih, sizeof bmih, 1/*count*/, pfile) != 1)
  44. goto GetOut;
  45. // Bogus info header check
  46. if (!(bmih.biSize == sizeof bmih && bmih.biPlanes == 1))
  47. goto GetOut;
  48. // Bogus bit depth? Only 8-bit supported.
  49. if (bmih.biBitCount != 8)
  50. goto GetOut;
  51. // Bogus compression? Only non-compressed supported.
  52. if (bmih.biCompression != 0) //BI_RGB)
  53. goto GetOut;
  54. // Figure out how many entires are actually in the table
  55. if (bmih.biClrUsed == 0)
  56. {
  57. bmih.biClrUsed = 256;
  58. cbPalBytes = (1 << bmih.biBitCount) * sizeof (mxBitmapRGBQuad);
  59. }
  60. else
  61. {
  62. cbPalBytes = bmih.biClrUsed * sizeof (mxBitmapRGBQuad);
  63. }
  64. // Read palette (bmih.biClrUsed entries)
  65. if (fread (rgrgbPalette, cbPalBytes, 1/*count*/, pfile) != 1)
  66. goto GetOut;
  67. image = new mxImage ();
  68. if (!image)
  69. goto GetOut;
  70. if (!image->create (bmih.biWidth, bmih.biHeight, 8))
  71. {
  72. goto GetOut;
  73. }
  74. pb = (byte *) image->palette;
  75. // Copy over used entries
  76. for (i = 0; i < (int) bmih.biClrUsed; i++)
  77. {
  78. *pb++ = rgrgbPalette[i].rgbRed;
  79. *pb++ = rgrgbPalette[i].rgbGreen;
  80. *pb++ = rgrgbPalette[i].rgbBlue;
  81. }
  82. // Fill in unused entires will 0,0,0
  83. for (i = bmih.biClrUsed; i < 256; i++)
  84. {
  85. *pb++ = 0;
  86. *pb++ = 0;
  87. *pb++ = 0;
  88. }
  89. // Read bitmap bits (remainder of file)
  90. cbBmpBits = bmfh.bfSize - ftell (pfile);
  91. pb = (byte *) malloc (cbBmpBits * sizeof (byte));
  92. if (pb == 0)
  93. {
  94. free (pbPal);
  95. goto GetOut;
  96. }
  97. if (fread (pb, cbBmpBits, 1/*count*/, pfile) != 1)
  98. {
  99. free (pb);
  100. free (pbPal);
  101. goto GetOut;
  102. }
  103. /*
  104. pbBmpBits = malloc(cbBmpBits);
  105. if (pbBmpBits == 0)
  106. {
  107. free (pb);
  108. free (pbPal);
  109. goto GetOut;
  110. }
  111. */
  112. pbBmpBits = (byte *) image->data;
  113. // data is actually stored with the width being rounded up to a multiple of 4
  114. biTrueWidth = (bmih.biWidth + 3) & ~3;
  115. // reverse the order of the data.
  116. pb += (bmih.biHeight - 1) * biTrueWidth;
  117. for(i = 0; i < bmih.biHeight; i++)
  118. {
  119. memmove (&pbBmpBits[biTrueWidth * i], pb, biTrueWidth);
  120. pb -= biTrueWidth;
  121. }
  122. pb += biTrueWidth;
  123. free (pb);
  124. success = true;
  125. GetOut:
  126. if (pfile)
  127. fclose (pfile);
  128. if ( !success )
  129. {
  130. delete image;
  131. image = 0;
  132. }
  133. return image;
  134. }
  135. bool
  136. mxBmpWrite (const char *filename, mxImage *image)
  137. {
  138. int i;
  139. FILE *pfile = 0;
  140. mxBitmapFileHeader bmfh;
  141. mxBitmapInfoHeader bmih;
  142. mxBitmapRGBQuad rgrgbPalette[256];
  143. int cbBmpBits;
  144. byte *pbBmpBits;
  145. byte *pb = 0;
  146. int cbPalBytes;
  147. int biTrueWidth;
  148. if (!image || !image->data || !image->palette)
  149. return false;
  150. // File exists?
  151. if ((pfile = fopen(filename, "wb")) == 0)
  152. return false;
  153. biTrueWidth = ((image->width + 3) & ~3);
  154. cbBmpBits = biTrueWidth * image->height;
  155. cbPalBytes = 256 * sizeof (mxBitmapRGBQuad);
  156. // Bogus file header check
  157. //bmfh.bfType = MAKEWORD( 'B', 'M' );
  158. bmfh.bfType = (word) (('M' << 8) | 'B');
  159. bmfh.bfSize = sizeof bmfh + sizeof bmih + cbBmpBits + cbPalBytes;
  160. bmfh.bfReserved1 = 0;
  161. bmfh.bfReserved2 = 0;
  162. bmfh.bfOffBits = sizeof bmfh + sizeof bmih + cbPalBytes;
  163. // Write file header
  164. if (fwrite (&bmfh, sizeof bmfh, 1/*count*/, pfile) != 1)
  165. {
  166. fclose (pfile);
  167. return false;
  168. }
  169. // Size of structure
  170. bmih.biSize = sizeof bmih;
  171. // Width
  172. bmih.biWidth = biTrueWidth;
  173. // Height
  174. bmih.biHeight = image->height;
  175. // Only 1 plane
  176. bmih.biPlanes = 1;
  177. // Only 8-bit supported.
  178. bmih.biBitCount = 8;
  179. // Only non-compressed supported.
  180. bmih.biCompression = 0; //BI_RGB;
  181. bmih.biSizeImage = 0;
  182. // huh?
  183. bmih.biXPelsPerMeter = 0;
  184. bmih.biYPelsPerMeter = 0;
  185. // Always full palette
  186. bmih.biClrUsed = 256;
  187. bmih.biClrImportant = 0;
  188. // Write info header
  189. if (fwrite (&bmih, sizeof bmih, 1/*count*/, pfile) != 1)
  190. {
  191. fclose (pfile);
  192. return false;
  193. }
  194. // convert to expanded palette
  195. pb = (byte *) image->palette;
  196. // Copy over used entries
  197. for (i = 0; i < (int) bmih.biClrUsed; i++)
  198. {
  199. rgrgbPalette[i].rgbRed = *pb++;
  200. rgrgbPalette[i].rgbGreen = *pb++;
  201. rgrgbPalette[i].rgbBlue = *pb++;
  202. rgrgbPalette[i].rgbReserved = 0;
  203. }
  204. // Write palette (bmih.biClrUsed entries)
  205. cbPalBytes = bmih.biClrUsed * sizeof (mxBitmapRGBQuad);
  206. if (fwrite (rgrgbPalette, cbPalBytes, 1/*count*/, pfile) != 1)
  207. {
  208. fclose (pfile);
  209. return false;
  210. }
  211. pbBmpBits = (byte *) malloc (cbBmpBits * sizeof (byte));
  212. if (!pbBmpBits)
  213. {
  214. fclose (pfile);
  215. return false;
  216. }
  217. pb = (byte *) image->data;
  218. // reverse the order of the data.
  219. pb += (image->height - 1) * image->width;
  220. for(i = 0; i < bmih.biHeight; i++)
  221. {
  222. memmove (&pbBmpBits[biTrueWidth * i], pb, image->width);
  223. pb -= image->width;
  224. }
  225. // Write bitmap bits (remainder of file)
  226. if (fwrite (pbBmpBits, cbBmpBits, 1/*count*/, pfile) != 1)
  227. {
  228. free (pbBmpBits);
  229. fclose (pfile);
  230. return false;
  231. }
  232. free (pbBmpBits);
  233. fclose (pfile);
  234. return true;
  235. }