• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

減色プログラム


Commit MetaInfo

Revision95078fb8e8ff46f6d0c811177d4ab407c3c3321a (tree)
Time2011-05-29 18:52:55
Authorberupon <berupon@gmai...>
Commiterberupon

Log Message

追加忘れ

Change Summary

Incremental Difference

--- /dev/null
+++ b/ImageIO/ImageIO_bmp.cpp
@@ -0,0 +1,183 @@
1+#include "stdafx.h"
2+#include "ImageIO_bmp.h"
3+
4+#include <stdio.h>
5+#define TRACE printf
6+#include <assert.h>
7+
8+#include <windows.h>
9+
10+static
11+bool Read_BITMAPINFOHEADER(IFile& file, BITMAPINFOHEADER& bmih)
12+{
13+ size_t fileSize = file.Size();
14+ if (fileSize <= 54) {
15+ TRACE("file size <= 54 bytes.");
16+ return false;
17+ }
18+ BITMAPFILEHEADER bmpFileHeader;
19+ size_t readBytes = 0;
20+ file.Read(&bmpFileHeader, 14, readBytes);
21+ assert(readBytes == 14);
22+ if (bmpFileHeader.bfType != 19778) {
23+ TRACE("file hedear bfType != 19778");
24+ return false;
25+ }
26+
27+ file.Read(&bmih, 40, readBytes);
28+ if (readBytes != 40) {
29+ TRACE("bmih shortage.");
30+ return false;
31+ }
32+
33+ return true;
34+}
35+
36+static
37+bool getImageInfo(ImageInfo& info, const BITMAPINFOHEADER& bmih)
38+{
39+ info.width = bmih.biWidth;
40+ info.height = bmih.biHeight;
41+ switch (bmih.biBitCount) {
42+ case 1:
43+ case 2:
44+ case 4:
45+ return false;
46+ break;
47+ case 8:
48+ info.bitsPerSample = 8;
49+ info.samplesPerPixel = 1;
50+ break;
51+ case 16:
52+ return false;
53+ case 24:
54+ info.bitsPerSample = 8;
55+ info.samplesPerPixel = 3;
56+ break;
57+ case 32:
58+ info.bitsPerSample = 8;
59+ info.samplesPerPixel = 4;
60+ break;
61+ }
62+ return true;
63+}
64+
65+bool ReadImageInfo_bmp(IFile& file, ImageInfo& info)
66+{
67+ BITMAPINFOHEADER bmih;
68+ if (!Read_BITMAPINFOHEADER(file, bmih)) {
69+ return false;
70+ }
71+ if (!getImageInfo(info, bmih)) {
72+ return false;
73+ }
74+ return true;
75+}
76+
77+bool ReadImage_bmp(IFile& file, ImageInfo& info, void* dest, int lineOffset, void* palettes)
78+{
79+ file.Seek(0, FILE_BEGIN);
80+
81+ BITMAPINFOHEADER bmih;
82+ if (!Read_BITMAPINFOHEADER(file, bmih)) {
83+ return false;
84+ }
85+ if (!getImageInfo(info, bmih)) {
86+ return false;
87+ }
88+ size_t bmiColorsLen = 0;
89+ switch (bmih.biBitCount) {
90+ case 1:
91+ bmiColorsLen = 2;
92+ break;
93+ case 4:
94+ bmiColorsLen = 16;
95+ break;
96+ case 8:
97+ bmiColorsLen = 256;
98+ break;
99+ case 16:
100+ TRACE("16 bit BMP not supported.");
101+ return false;
102+ break;
103+ case 32:
104+ if (bmih.biCompression == BI_BITFIELDS) {
105+ bmiColorsLen = 3;
106+ }
107+ }
108+ size_t readBytes = 0;
109+ if (bmiColorsLen) {
110+ size_t needBytes = /*sizeof(RGBQUAD)*/4*bmiColorsLen;
111+ file.Read(palettes, needBytes, readBytes);
112+ if (readBytes != needBytes) {
113+ TRACE("bmiColors read failed.");
114+ return false;
115+ }
116+ }
117+ const int lineBytes = ((((bmih.biWidth * bmih.biBitCount) + 31) & ~31) >> 3);
118+ const int lineIdx = (bmih.biHeight < 0) ? 0 : (bmih.biHeight-1);
119+ OffsetPtr(dest, lineOffset * lineIdx);
120+ lineOffset *= (bmih.biHeight < 0) ? 1 : -1;
121+
122+ const size_t height = abs(bmih.biHeight);
123+ for (size_t y=0; y<height; ++y) {
124+ file.Read(dest, lineBytes, readBytes);
125+ if (readBytes != lineBytes) {
126+ TRACE("read bytes != lineBytes.");
127+ return false;
128+ }
129+ OffsetPtr(dest, lineOffset);
130+ }
131+
132+ return true;
133+}
134+
135+bool WriteImage_bmp(IFile& file, const ImageInfo& info, const void* data, int lineOffset)
136+{
137+ file.Seek(0, FILE_BEGIN);
138+
139+ if (info.bitsPerSample % 8) {
140+ return false;
141+ }
142+
143+ const size_t bitsPerPixel = info.bitsPerSample * info.samplesPerPixel;
144+ const size_t imageSize = info.width * info.height * (bitsPerPixel / 8);
145+ size_t nBytesWritten;
146+ {
147+ BITMAPFILEHEADER bfh;
148+ bfh.bfType = 19778; // BM
149+ bfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + imageSize;
150+ bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
151+ file.Write(&bfh, sizeof(bfh), nBytesWritten);
152+ }
153+
154+ {
155+ BITMAPINFOHEADER bmih;
156+ bmih.biSize = sizeof(bmih);
157+ bmih.biWidth = info.width;
158+ bmih.biHeight = info.height;
159+ bmih.biPlanes = 1;
160+ bmih.biBitCount = bitsPerPixel;
161+ bmih.biCompression = BI_RGB;
162+ bmih.biSize = imageSize;
163+ bmih.biXPelsPerMeter = bmih.biYPelsPerMeter = 0;
164+ bmih.biClrUsed = 0;
165+ bmih.biClrImportant = 0;
166+ file.Write(&bmih, sizeof(bmih), nBytesWritten);
167+ }
168+
169+ const void* pLine = ((const uint8_t*)data + lineOffset * (info.height-1));
170+ const size_t lineBytes = ((((info.width * bitsPerPixel) + 31) & ~31) >> 3);
171+ for (size_t y=0; y<info.height; ++y) {
172+ file.Write(pLine, lineBytes, nBytesWritten);
173+ if (nBytesWritten != lineBytes) {
174+ TRACE("nBytesWritten != lineBytes.");
175+ return false;
176+ }
177+ OffsetPtr(pLine, -lineOffset);
178+ }
179+
180+ return true;
181+
182+}
183+
--- /dev/null
+++ b/ImageIO/ImageIO_bmp.h
@@ -0,0 +1,9 @@
1+#pragma once
2+
3+#include "ImageIO.h"
4+
5+bool ReadImageInfo_bmp(IFile& file, ImageInfo& info);
6+bool ReadImage_bmp(IFile& file, ImageInfo& info, void* dest, int lineOffset, void* palettes);
7+
8+bool WriteImage_bmp(IFile& file, const ImageInfo& info, const void* data, int lineOffset);
9+