aboutsummaryrefslogtreecommitdiff
path: root/KaplaDemo/samples/sampleViewer3/BmpFile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'KaplaDemo/samples/sampleViewer3/BmpFile.cpp')
-rw-r--r--KaplaDemo/samples/sampleViewer3/BmpFile.cpp184
1 files changed, 184 insertions, 0 deletions
diff --git a/KaplaDemo/samples/sampleViewer3/BmpFile.cpp b/KaplaDemo/samples/sampleViewer3/BmpFile.cpp
new file mode 100644
index 00000000..50c213a2
--- /dev/null
+++ b/KaplaDemo/samples/sampleViewer3/BmpFile.cpp
@@ -0,0 +1,184 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "BmpFile.h"
+
+static bool isBigEndian() { int i = 1; return *((char*)&i)==0; }
+
+static unsigned short endianSwap(unsigned short nValue)
+{
+ return (((nValue>> 8)) | (nValue << 8));
+
+}
+
+static unsigned int endianSwap(unsigned int i)
+{
+ unsigned char b1, b2, b3, b4;
+
+ b1 = i & 255;
+ b2 = ( i >> 8 ) & 255;
+ b3 = ( i>>16 ) & 255;
+ b4 = ( i>>24 ) & 255;
+
+ return ((unsigned int)b1 << 24) + ((unsigned int)b2 << 16) + ((unsigned int)b3 << 8) + b4;
+}
+
+// -------------------------------------------------------------------
+
+#pragma pack(1)
+
+struct BMPHEADER {
+ unsigned short Type;
+ unsigned int Size;
+ unsigned short Reserved1;
+ unsigned short Reserved2;
+ unsigned int OffBits;
+};
+
+// Only Win3.0 BMPINFO (see later for OS/2)
+struct BMPINFO {
+ unsigned int Size;
+ unsigned int Width;
+ unsigned int Height;
+ unsigned short Planes;
+ unsigned short BitCount;
+ unsigned int Compression;
+ unsigned int SizeImage;
+ unsigned int XPelsPerMeter;
+ unsigned int YPelsPerMeter;
+ unsigned int ClrUsed;
+ unsigned int ClrImportant;
+};
+
+#pragma pack()
+
+// Compression Type
+#define BI_RGB 0L
+#define BI_RLE8 1L
+#define BI_RLE4 2L
+
+// -------------------------------------------------------------------
+BmpLoaderBuffer::BmpLoaderBuffer()
+{
+ mWidth = 0;
+ mHeight = 0;
+ mRGB = NULL;
+}
+
+
+// -------------------------------------------------------------------
+BmpLoaderBuffer::~BmpLoaderBuffer()
+{
+ if (mRGB) free(mRGB);
+}
+
+// -------------------------------------------------------------------
+bool BmpLoaderBuffer::loadFile(const char *filename)
+{
+ if (mRGB) {
+ free(mRGB);
+ mRGB = NULL;
+ }
+ mWidth = 0;
+ mHeight = 0;
+
+ FILE *f = fopen(filename, "rb");
+ if (!f)
+ return false;
+
+ size_t num;
+ BMPHEADER header;
+ num = fread(&header, sizeof(BMPHEADER), 1, f);
+ if(isBigEndian()) header.Type = endianSwap(header.Type);
+ if (num != 1) { fclose(f); return false; }
+ if (header.Type != 'MB') { fclose(f); return false; }
+
+ BMPINFO info;
+ num = fread(&info, sizeof(BMPINFO), 1, f);
+ if (num != 1) { fclose(f); return false; }
+ if(isBigEndian()) info.Size = endianSwap(info.Size);
+ if(isBigEndian()) info.BitCount = endianSwap(info.BitCount);
+ if(isBigEndian()) info.Compression = endianSwap(info.Compression);
+ if(isBigEndian()) info.Width = endianSwap(info.Width);
+ if(isBigEndian()) info.Height = endianSwap(info.Height);
+
+ if (info.Size != sizeof(BMPINFO)) { fclose(f); return false; }
+ if (info.BitCount != 24) { fclose(f); return false; }
+ if (info.Compression != BI_RGB) { fclose(f); return false; }
+
+ mWidth = info.Width;
+ mHeight = info.Height;
+ mRGB = (unsigned char*)malloc(mWidth * mHeight * 3);
+
+ int lineLen = (((info.Width * (info.BitCount>>3)) + 3)>>2)<<2;
+ unsigned char *line = (unsigned char *)malloc(lineLen);
+
+ for(int i = info.Height-1; i >= 0; i--) {
+ num = fread(line, lineLen, 1, f);
+ if (num != 1) { fclose(f); return false; }
+ unsigned char *src = line;
+ unsigned char *dest = mRGB + i*info.Width*3;
+ for(unsigned int j = 0; j < info.Width; j++) {
+ unsigned char r,g,b;
+ b = *src++; g = *src++; r = *src++;
+ *dest++ = r; *dest++ = g; *dest++ = b;
+ }
+ }
+
+ free(line);
+ fclose(f);
+
+ return true;
+}
+
+// -------------------------------------------------------------------
+bool saveBmpRBG(const char *filename, int width, int height, void *data)
+{
+ FILE *f = fopen(filename, "wb");
+ if (!f) return false;
+
+ // todo : works on pcs only, swap correctly if big endian
+ BMPHEADER header;
+ header.Type = 'MB';
+ header.Size = sizeof(BMPINFO);
+ header.Reserved1 = 0;
+ header.Reserved2 = 0;
+ header.OffBits = sizeof(BMPHEADER) + sizeof(BMPINFO);
+ fwrite(&header, sizeof(BMPHEADER), 1, f);
+
+ BMPINFO info;
+ info.Size = sizeof(BMPINFO);
+ info.Width = width;
+ info.Height = height;
+ info.Planes = 1;
+ info.BitCount = 24;
+ info.Compression = BI_RGB;
+ info.XPelsPerMeter = 4000;
+ info.YPelsPerMeter = 4000;
+ info.ClrUsed = 0;
+ info.ClrImportant = 0;
+ fwrite(&info, sizeof(info), 1, f);
+
+ // padded to multiple of 4
+ int lineLen = (((info.Width * (info.BitCount>>3)) + 3)>>2)<<2;
+ info.SizeImage = lineLen * height;
+
+ unsigned char *line = (unsigned char *)malloc(lineLen);
+
+ for(int i = 0; i < height; i++) {
+ unsigned char *src = (unsigned char*)data + i*width*3;
+ unsigned char *dest = line;
+ for(int j = 0; j < width; j++) {
+ unsigned char r,g,b;
+ r = *src++; g = *src++; b = *src++;
+ *dest++ = b; *dest++ = g; *dest++ = r;
+ }
+ for (int j = 3*width; j < lineLen; j++)
+ *dest++ = 0;
+ fwrite(line, lineLen, 1, f);
+ }
+
+ free(line);
+ fclose(f);
+
+ return true;
+} \ No newline at end of file