#include <stdio.h>
#include <math.h>
#define C_PI (3.14159265358979323846264338328) /* pi */
#define RGB(r,g,b) (((r) << 16) | ((g) << 8) | (b))
/*
int hsvtorgb(int h, int s, int v);
h = 0〜1535 色相
0〜255 赤〜黄色
256〜511 黄色〜緑
512〜767 緑〜シアン
768〜1023 シアン〜青
1024〜1279 青〜マゼンダ
1280〜1535 マゼンダ〜赤
s = 0〜255 彩度(白レベル)
0〜255 白〜原色
v = 0〜255 明度(黒レベル)
0〜255 黒〜原色
hsvtorgb() = (r << 16) | (g << 8) | b
r = 0〜255 赤の成分
g = 0〜255 緑の成分
b = 0〜255 青の成分
*/
int hsvtorgb(int h, int s, int v)
{
int f, f1, s1, v1, w, d;
if (s == 0) {
return RGB(v, v, v);
}
f = h & 255;
f1 = (f << 1) | 1;
s1 = (s << 1) | 1;
v1 = (v << 1) | 1;
w = v - ((s1 * v1 + (1 << 9)) >> 10);
d = (f1 * s1 * v1 + (1 << 18)) >> 19;
switch (h >> 8) {
case 0: return RGB(v, w+d, w);
case 1: return RGB(v-d, v, w);
case 2: return RGB(w, v, w+d);
case 3: return RGB(w, v-d, v);
case 4: return RGB(w+d, w, v);
case 5: return RGB(v, w, v-d);
}
}
/* パレットテーブルを作る */
/* 返却値: パレットテーブルの先頭,NULL=メモリが不足している */
int *make_palet_table(int mxCnt)
{
int *paTable, *p;
int n;
if ((paTable = (int *)malloc((mxCnt + 1) * sizeof(int))) == NULL) {
fprintf(stderr, "メモリが不足しています\n");
return NULL;
}
p = paTable;
for (n = 0; n < mxCnt; n++) {
double t = n / (mxCnt / 15.0);
int u, v;
u = (int)(cos((t) * C_PI) * 112.0 + 212.0);
u = (u <= 255) ? u : 255;
v = (int)(cos((t + 1.0) * C_PI) * 72.0 + 188.0);
v = (v <= 255) ? v : 255;
*p++ = hsvtorgb((1536 * n) / mxCnt, u, v);
}
*p = 0;
return paTable;
}
/* BMPファイルのヘッダ */
char bmpHeader[54] = {
'B', 'M', /* [ 0] ファイルタイプ */
0, 0, 0, 0, /* [ 2] ファイルサイズ */
0, 0, 0, 0, /* [ 6] 予約 */
0x36, 0, 0, 0, /* [10] ビットマップデータのシーク位置 */
0x28, 0, 0, 0, /* [14] ここから始まるヘッダの長さ */
0, 0, 0, 0, /* [18] ビットマップの幅 */
0, 0, 0, 0, /* [22] ビットマップの高さ */
0x01, 0, /* [26] プレーン数 */
0x18, 0, /* [28] 1ピクセルあたりのビット数(1,4,8,24) */
0, 0, 0, 0, /* [30] 圧縮タイプ(0=非圧縮) */
0, 0, 0, 0, /* [34] ビットマップデータの長さ */
0x20, 0x2e, 0, 0, /* [38] 水平解像度(px/m) */
0x20, 0x2e, 0, 0, /* [42] 垂直解像度(px/m) */
0, 0, 0, 0, /* [46] カラーインデックス数 */
0, 0, 0, 0 /* [50] 重要なカラーインデックス数 */
}; /* [54] */
/* 32ビットの数値をlittle-endianで書き込む */
void wl4(char *p, int value)
{
*p++ = value & 0xff;
*p++ = (value >> 8) & 0xff;
*p++ = (value >> 16) & 0xff;
*p++ = (value >> 24) & 0xff;
}
/* 24ビットのBMPファイルを出力する */
/* 返却値:0=正常終了,1=異常終了 */
int output_bmp(char *bmpName, int *paTable, int *cntTable, int width, int height)
{
FILE *fp;
int *p;
int n;
/* BMPファイルのヘッダを作る */
wl4(&bmpHeader[ 2], sizeof(bmpHeader) + 3 * width * height);
wl4(&bmpHeader[34], 3 * width * height);
wl4(&bmpHeader[18], width);
wl4(&bmpHeader[22], height);
/* BMPファイルを作る */
if ((fp = fopen(bmpName, "wb")) == NULL) {
fprintf(stderr, "ファイルが作れません … %s\n", bmpName);
return 1;
}
/* BMPファイルのヘッダを出力する */
for (n = 0; n < sizeof(bmpHeader); n++) {
fputc(bmpHeader[n], fp);
}
/* ビットマップデータを出力する */
p = cntTable;
n = width * height;
while (n--) {
int rgb = paTable[*p++];
fputc(rgb & 255, fp); /* B */
fputc((rgb >> 8) & 255, fp); /* G */
fputc((rgb >> 16) & 255, fp); /* R */
}
fclose(fp);
return 0;
}
|