home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <libc.h>
-
- #include "bmp.h"
-
- static xdelta, ydelta, compmode;
-
- static int bmpGetPalette(FILE *fp, bmpHeader *bh)
- /* ¥±¥ò¥ˆ¥¨⁄ù˘²⁄ë„⁄ú⁄˙⁄‰⁄˛˛˛®Ł⁄˛¹Ł˘‹¥¢¥²¥ò¥„⁄ù bh->palette⁄¸´ï˘¡£
- ¥¤¥Ø¡…⁄˛»¡¢⁄“⁄Ł⁄½24¥½¥ˆ¥¨¥«¥Ø¡…⁄˛»⁄¸⁄ˇ NULL ⁄‹˘⁄º¡£
- ˚á⁄Œˆ˝⁄ˇ¡¢¹fi‚ø⁄˛¬ò„ñ 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] ⁄¸¥»¥ˆ¥¨⁄„⁄º¡£‡˘¿§⁄¸²‹˝â⁄˚¥¾¥fl¥»¥º¿û⁄ˇ
- 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;
- }
-