This is bmpimage.c in view mode; [Download] [Up]
#include <stdio.h>
#include <libc.h>
#include "bmp.h"
static xdelta, ydelta, compmode;
static int bmpGetPalette(FILE *fp, bmpHeader *bh)
/* ¥Ñ¥ì¥Ã¥È¤òÆÉ¤ß¹þ¤ó¤Ç¤½¤ÎÎΰè¤ÎÀèÆ¬¥¢¥É¥ì¥¹¤ò bh->palette¤ËÂåÆþ¡£
¥¨¥é¡¼¤Î»þ¡¢¤ª¤è¤Ó24¥Ó¥Ã¥È¥«¥é¡¼¤Î»þ¤Ë¤Ï NULL ¤¬Æþ¤ë¡£
ÊÖ¤êÃͤϡ¢À®¸ù¤Î¾ì¹ç 0, ¥¨¥é¡¼¤Î¾ì¹ç¤Ï¸¶°ø(!=0)¡£ */
{
int i, color;
paltype *pal = NULL;
unsigned char *p;
bh->palette = NULL;
if (bh->bits == 24) /* 24¥Ó¥Ã¥È¥«¥é¡¼¤Ï¥Ñ¥ì¥Ã¥ÈÉÔÍ× */
return 0;
color = 1 << bh->bits;
pal = (paltype *)malloc(sizeof(paltype) * color);
if (bh->type == OS2) {
for (i = 0; i < color; i++) {
p = pal[i];
p[BLUE] = getc(fp);
p[GREEN] = getc(fp);
p[RED] = getc(fp);
}
}else { /* WIN3 */
for (i = 0; i < color; i++) {
p = pal[i];
p[BLUE] = getc(fp);
p[GREEN] = getc(fp);
p[RED] = getc(fp);
(void) getc(fp);
}
}
bh->palette = pal;
if (feof(fp) || fseek(fp, bh->bitoffset, SEEK_SET) < 0)
return Err_SHORT;
return 0;
}
static int get1dot(FILE *fp, int wid, unsigned char *ln)
{
int x, cnt, cc, mask;
if (feof(fp))
return -1;
for (x = 0, cnt = 0; x < wid; cnt++) {
cc = getc(fp);
for (mask = 0x80; mask; mask >>= 1)
ln[x++] = (cc & mask) ? 1 : 0;
}
for ( ; cnt & 0x03; cnt++)
(void) getc(fp);
return 0;
}
static int get4dots(FILE *fp, int wid, unsigned char *ln)
{
int x, cnt, cc;
if (feof(fp))
return -1;
for (x = 0, cnt = 0; x < wid; cnt++) {
cc = getc(fp);
ln[x++] = cc >> 4;
ln[x++] = (cc & 0x0f);
}
for ( ; cnt & 0x03; cnt++)
(void) getc(fp);
return 0;
}
static int get8dots(FILE *fp, int wid, unsigned char *ln)
{
int cnt;
if (feof(fp))
return -1;
for (cnt = 0; cnt < wid; cnt++)
ln[cnt] = getc(fp);
for ( ; cnt & 0x03; cnt++)
(void) getc(fp);
return 0;
}
static int rledots(FILE *fp, int wid, unsigned char *ln)
{
int i, j, k, cc, count;
int half[2];
if (feof(fp))
return -1;
for (i = 0; i < wid; i++)
ln[i] = 0;
if (ydelta > 0) {
ydelta--;
return 0;
}
count = wid;
if (xdelta > 0) {
if (xdelta > count) {
xdelta = 0;
return 0;
}
count -= xdelta;
ln += xdelta;
}
xdelta = 0;
for ( ; ; ) {
i = getc(fp);
if (i) { /* Codec Mode */
if (i > count) i = count;
count -= i;
cc = getc(fp);
if (compmode == RLE8) {
while (i-- > 0)
*ln++ = cc;
}else {
half[0] = cc >> 4;
half[1] = cc & 0x0f;
for (k = 0; i-- > 0; k ^= 1)
*ln++ = half[k];
}
continue;
}
/* Absolute Mode */
j = getc(fp);
if (j == 0 || j == 1) /* EOL / EOF */
break; /* return */
if (j == 2) { /* Delta Mode */
xdelta = getc(fp); /* X-offset */
ydelta = getc(fp); /* Y-offset */
if (ydelta == 0) {
count -= xdelta;
ln += xdelta;
xdelta = 0;
}else {
xdelta += wid - count;
ydelta--;
break; /* return */
}
}else {
if (j > count) j = count;
count -= j;
if (compmode == RLE8) {
k = j & 1; /* 16-bit packing */
while (j-- > 0)
*ln++ = getc(fp);
}else {
k = (j + 1) & 2; /* 16-bit packing */
while (j-- > 0) {
cc = getc(fp);
*ln++ = cc >> 4;
if (j-- <= 0)
break;
*ln++ = cc & 0x0f;
}
}
if (k)
(void) getc(fp);
}
}
return 0;
}
int bmpGetImage(FILE *fp, bmpHeader *bh, int *bits, unsigned char **planes)
/* ¥Õ¥¡¥¤¥ë¤«¤é¥¤¥á¡¼¥¸¥Ç¡¼¥¿¤òÆÉ¤ß½Ð¤·¡¢R,G,B ¤Î£³¤Ä¤Î¥×¥ì¡¼¥ó¤ÎÀèÆ¬
¥¢¥É¥ì¥¹¤ò planes[0]~[2] ¤Ë¥»¥Ã¥È¤¹¤ë¡£³Æ¿§¤ËɬÍפʥԥ¯¥»¥ë¿ô¤Ï
bits ¤ËÆþ¤ì¤é¤ì¤ë¡£mh¤Ë¤Ï¥Ø¥Ã¥À¾öÊó¤ò»ØÄꤹ¤ë¡£ */
{
int x, wid, y, w;
int colbit = 8, colnum = 0;
int err = 0;
BOOL isgray = NO;
int (*getNdots)(FILE *, int, unsigned char *) = get8dots;
if (bh->comp) {
if (bh->comp == RLE8)
colnum = 256;
else if (bh->comp == RLE4)
colnum = 16;
else
return Err_IMPLEMENT;
compmode = bh->comp;
getNdots = rledots;
}else {
compmode = NoComp;
if (bh->bits == 1)
getNdots = get1dot;
else if (bh->bits == 4)
getNdots = get4dots;
else if (bh->bits == 8)
getNdots = get8dots;
colnum = 1 << bh->bits;
} /* else bits == 24 */
if ((err = bmpGetPalette(fp, bh)) != 0)
return err;
if (colnum && bh->bits < 24) {
colbit = howManyBits(bh->palette, colnum);
isgray = isGray(bh->palette, colnum);
}
wid = byte_length(colbit, bh->x);
err = allocImage(planes, bh->x, bh->y, colbit, (isgray ? 1 : 3));
if (err)
return err;
if (bh->bits <= 8) {
unsigned char line[MAXWidth];
unsigned char *map[MAXPLANE];
*bits = colbit;
for (y = bh->y - 1; y >= 0; y--) {
if (getNdots(fp, bh->x, line) < 0)
return Err_SHORT;
map[0] = planes[0] + (w = wid * y);
map[1] = planes[1] + w;
map[2] = planes[2] + w;
expandImage(map, line, (const paltype *)bh->palette,
colbit, bh->x, isgray, -1);
}
}else {
unsigned char *rr, *gg, *bb;
*bits = 8;
for (y = bh->y - 1; y >= 0; y--) {
if (feof(fp))
return Err_SHORT;
rr = planes[0] + (w = wid * y);
gg = planes[1] + w;
bb = planes[2] + w;
for (x = 0; x < wid; x++) {
*bb++ = getc(fp);
*gg++ = getc(fp);
*rr++ = getc(fp);
}
for (x *= 3 ; x & 0x03; x++)
(void) getc(fp);
}
}
return 0;
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.