PNGもなんとかなったので今度は
TGAに挑戦です。
TGAを扱うライブラリには
libtgaとその改造版の
libtga-exがあります。
で、使い方を確認するために、とりあえずこんなのを書いてみました。
/* TARGA2BGR */
#include <stdio.h>
#include <stdlib.h>
#include "tga.h"
typedef struct {
TGA *tga;
unsigned char *buff;
} tga_read_t;
int close(const char *msg, tga_read_t *tr, int ret)
{
fprintf(stderr, "%s\n", msg);
if (tr->buff) {
free(tr->buff);
}
if (tr->tga) {
TGAClose(tr->tga);
}
return ret;
}
int main(int argc, char **argv)
{
if (argc < 2) {
return -1;
}
tga_read_t tr = {0};
tr.tga = TGAOpen(argv[1], "rb");
if (!tr.tga || tr.tga->last != TGA_OK) {
return close("TGAOpen failed", &tr, -1);
}
if (TGAReadHeader(tr.tga) != TGA_OK) {
return close("TGAReadHeader failed", &tr, -1);
}
fprintf(stderr, "width: %u\n", tr.tga->hdr.width);
fprintf(stderr, "height: %u\n", tr.tga->hdr.height);
fprintf(stderr, "depth: %d\n", tr.tga->hdr.depth);
fprintf(stderr, "alpha: %d\n", tr.tga->hdr.alpha);
size_t buf_size
= tr.tga->hdr.width * tr.tga->hdr.height * tr.tga->hdr.depth >> 3;
tr.buff = malloc(buf_size);
if (!tr.buff) {
return close("malloc failed", &tr, -1);
}
if (TGAReadScanlines(tr.tga, tr.buff, 0, tr.tga->hdr.height, TGA_BGR)
!= tr.tga->hdr.height) {
return close("couldn't read all lines\n", &tr, -1);
}
char out_name[1024];
sprintf(out_name, "%s.raw", argv[1]);
FILE *out = fopen(out_name, "wb");
if (!out) {
return close("open output file failed", &tr, -1);
}
fwrite(tr.buff, 1, buf_size, out);
fclose(out);
return close("finish", &tr, 0);
}
こいつにtgaファイルを食わせてやればBGRなrawデータとして出力するわけですが、試しにtgaではないファイルを食わせるとなぜかクラッシュします。
いちおうTGAReadHeaderのところでチェックはしているみたいなんですが…はて?
で、TGAReadHeaderの部分のコードを読んでみると
int TGAReadHeader (TGA *tga)
{
tbyte *tmp;
if (!tga) return 0;
__TGASeek(tga, 0, SEEK_SET);
if (tga->off != 0) {
TGA_ERROR(tga, TGA_SEEK_FAIL);
return 0;
}
/* 中略 */
return TGA_OK;
}
と問題なしならTGA_OKを返し、問題有りなら0を返すようになっています。
ではTGA_OKの中身は何かとtga.hのほうを読んでみると…
/* error codes */
enum {
TGA_OK = 0, /* success */
TGA_ERROR,
TGA_OOM, /* out of memory */
TGA_OPEN_FAIL,
TGA_SEEK_FAIL,
TGA_READ_FAIL,
TGA_WRITE_FAIL,
TGA_UNKNOWN_SUB_FORMAT /* invalid bit depth */
};
TGA_OKが全然OKになってねえよ…そりゃクラッシュもするわ。
なんで誰もこれを直してないんだ?