Login | ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/ipe_artfile_utils/trunk/ipe16_bmpexport.c
Revision: 2
Committed: Thu Nov 8 11:19:36 2018 UTC (18 months, 3 weeks ago) by daniel-marschall
Content type: text/x-csrc
File size: 3188 byte(s)
Log Message:
Initial release to SVN

File Contents

# Content
1 /**
2 * Bitmap Export for Imagination Pilots Entertainment 16-bit games (IPE16)
3 * - Blown Away - The Interactive Game by Imagination Pilots (BA)
4 * - Panic in the Park - The Interactive Game by Imagination Pilots (PiP)
5 * - Where's Waldo? At the Circus (Waldo1)
6 * ART file packer and unpacker by Daniel Marschall, ViaThinkSoft (C) 2014-2018
7 * Revision: 2018-02-15
8 **/
9
10 #include <stdio.h>
11 #include <stdint.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <assert.h>
15
16 #include "ipe16_bmpexport.h"
17
18 #define BMP_LINE_PADDING 4
19
20 // Windows 98 does not support top-down bitmaps, so we need to flip everything
21 #define USE_BOTTOMUP
22
23 RGBQUAD ipe16_rgb_to_rgbquad(Ipe16ColorTableEntry cte) {
24 RGBQUAD ret;
25 ret.rgbRed = cte.r;
26 ret.rgbGreen = cte.g;
27 ret.rgbBlue = cte.b;
28 ret.rgbReserved = 0;
29 return ret;
30 }
31
32 void ipe16_write_bmp(FILE* output, unsigned int width, unsigned int height, unsigned char* imagedata, size_t imagedata_len, Ipe16ColorTable ct) {
33
34 #ifdef USE_BOTTOMUP
35 const size_t bmpDataSize = width*height;
36 unsigned char* bmpData = (unsigned char*)malloc(bmpDataSize);
37 assert(bmpData != NULL);
38 int h;
39 for (h=0; h<height; ++h) {
40 int idx_dest = (height-1)-h;
41 int idx_src = h;
42 assert(idx_src*width >= 0);
43 assert(idx_dest*width >= 0);
44 memcpy(bmpData+idx_dest*width, imagedata+idx_src*width, width);
45 }
46 imagedata = bmpData;
47 #endif
48
49 // Each line must be padded to a multiple of 4
50 int pad = (BMP_LINE_PADDING - (width % BMP_LINE_PADDING)) % BMP_LINE_PADDING;
51 int newwidth = width+pad;
52 int newsize = newwidth * height;
53 unsigned char* padded_imagedata = (unsigned char*)malloc(newsize);
54 int i;
55 for (i=0; i<height; ++i) {
56 int offset = newwidth*i;
57 memcpy(&padded_imagedata[offset], imagedata, width);
58 memset(&padded_imagedata[offset+width], 0, pad);
59 imagedata += width;
60 }
61
62 // Color table in a bitmap is BGR0, while Blown Away uses RGB
63 const unsigned int NUM_COLORS = sizeof(ct.colors)/sizeof(ct.colors[0]);
64 RGBQUAD rgba_colortable[NUM_COLORS];
65 for (i=0; i<NUM_COLORS; ++i) {
66 rgba_colortable[i] = ipe16_rgb_to_rgbquad(ct.colors[i]);
67 }
68
69 BITMAPFILEHEADER bfh;
70 bfh.bfType = BI_SIGNATURE;
71 bfh.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(rgba_colortable)+newsize;
72 bfh.bfReserved1 = 0;
73 bfh.bfReserved2 = 0;
74 bfh.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(rgba_colortable);
75 fwrite(&bfh, sizeof(bfh), 1, output);
76
77 BITMAPINFOHEADER bih;
78 bih.biSize = sizeof(BITMAPINFOHEADER);
79 bih.biWidth = width;
80 #ifdef USE_BOTTOMUP
81 bih.biHeight = height; // (positive = "bottom-up"-Bitmap)
82 #else
83 bih.biHeight = -height; // (negative = "top-down"-Bitmap)
84 #endif
85 bih.biPlanes = 1;
86 bih.biBitCount = 8;
87 bih.biCompression = BI_RGB;
88 bih.biSizeImage = 0;
89 bih.biXPelsPerMeter = 0;
90 bih.biYPelsPerMeter = 0;
91 bih.biClrUsed = 0;
92 bih.biClrImportant = 0;
93 fwrite(&bih, sizeof(bih), 1, output);
94
95 // Color table
96 fwrite(rgba_colortable, sizeof(rgba_colortable), 1, output);
97
98 // Image data
99 fwrite(padded_imagedata, newsize, 1, output);
100
101 free(padded_imagedata);
102 #ifdef USE_BOTTOMUP
103 free(bmpData);
104 #endif
105 }
106

Properties

Name Value
svn:mime-type text/x-csrc