Subversion Repositories ipe_artfile_utils

Compare Revisions

No changes between revisions

Regard whitespace Rev 1 → Rev 2

/trunk/ipe16_bmpexport.c
0,0 → 1,106
/**
* Bitmap Export for Imagination Pilots Entertainment 16-bit games (IPE16)
* - Blown Away - The Interactive Game by Imagination Pilots (BA)
* - Panic in the Park - The Interactive Game by Imagination Pilots (PiP)
* - Where's Waldo? At the Circus (Waldo1)
* ART file packer and unpacker by Daniel Marschall, ViaThinkSoft (C) 2014-2018
* Revision: 2018-02-15
**/
 
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
 
#include "ipe16_bmpexport.h"
 
#define BMP_LINE_PADDING 4
 
// Windows 98 does not support top-down bitmaps, so we need to flip everything
#define USE_BOTTOMUP
 
RGBQUAD ipe16_rgb_to_rgbquad(Ipe16ColorTableEntry cte) {
RGBQUAD ret;
ret.rgbRed = cte.r;
ret.rgbGreen = cte.g;
ret.rgbBlue = cte.b;
ret.rgbReserved = 0;
return ret;
}
 
void ipe16_write_bmp(FILE* output, unsigned int width, unsigned int height, unsigned char* imagedata, size_t imagedata_len, Ipe16ColorTable ct) {
 
#ifdef USE_BOTTOMUP
const size_t bmpDataSize = width*height;
unsigned char* bmpData = (unsigned char*)malloc(bmpDataSize);
assert(bmpData != NULL);
int h;
for (h=0; h<height; ++h) {
int idx_dest = (height-1)-h;
int idx_src = h;
assert(idx_src*width >= 0);
assert(idx_dest*width >= 0);
memcpy(bmpData+idx_dest*width, imagedata+idx_src*width, width);
}
imagedata = bmpData;
#endif
 
// Each line must be padded to a multiple of 4
int pad = (BMP_LINE_PADDING - (width % BMP_LINE_PADDING)) % BMP_LINE_PADDING;
int newwidth = width+pad;
int newsize = newwidth * height;
unsigned char* padded_imagedata = (unsigned char*)malloc(newsize);
int i;
for (i=0; i<height; ++i) {
int offset = newwidth*i;
memcpy(&padded_imagedata[offset], imagedata, width);
memset(&padded_imagedata[offset+width], 0, pad);
imagedata += width;
}
 
// Color table in a bitmap is BGR0, while Blown Away uses RGB
const unsigned int NUM_COLORS = sizeof(ct.colors)/sizeof(ct.colors[0]);
RGBQUAD rgba_colortable[NUM_COLORS];
for (i=0; i<NUM_COLORS; ++i) {
rgba_colortable[i] = ipe16_rgb_to_rgbquad(ct.colors[i]);
}
 
BITMAPFILEHEADER bfh;
bfh.bfType = BI_SIGNATURE;
bfh.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(rgba_colortable)+newsize;
bfh.bfReserved1 = 0;
bfh.bfReserved2 = 0;
bfh.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(rgba_colortable);
fwrite(&bfh, sizeof(bfh), 1, output);
 
BITMAPINFOHEADER bih;
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biWidth = width;
#ifdef USE_BOTTOMUP
bih.biHeight = height; // (positive = "bottom-up"-Bitmap)
#else
bih.biHeight = -height; // (negative = "top-down"-Bitmap)
#endif
bih.biPlanes = 1;
bih.biBitCount = 8;
bih.biCompression = BI_RGB;
bih.biSizeImage = 0;
bih.biXPelsPerMeter = 0;
bih.biYPelsPerMeter = 0;
bih.biClrUsed = 0;
bih.biClrImportant = 0;
fwrite(&bih, sizeof(bih), 1, output);
 
// Color table
fwrite(rgba_colortable, sizeof(rgba_colortable), 1, output);
 
// Image data
fwrite(padded_imagedata, newsize, 1, output);
 
free(padded_imagedata);
#ifdef USE_BOTTOMUP
free(bmpData);
#endif
}
 
Property changes:
Added: svn:mime-type
+text/x-csrc
\ No newline at end of property