/* $Header: /home/yav/xpx/RCS/tim.c,v 1.7 1996/04/24 23:08:27 yav Exp $ * * TIM file access routine for xpx * written by yav (UHD98984@pcvan.or.jp) * * * WARNING: * * Permission to use and distribute this source is granted without fee. * But, It is not permitted to analyze this source without license. * * */ #include #include "xpx.h" #include "headers.h" #include "work.h" #define PUBLIC_TIM_C #include "extern.h" char rcsid_tim[] = "$Id: tim.c,v 1.7 1996/04/24 23:08:27 yav Exp $"; /* * TIM - Tohshinden image file format * * +0: Header block * +0 - 3 magic number? * +4 - 7 bit1-0: bytes per pixel * (0: 4bits per pixel) * bit3-2: bytes per color * (0: no CLUT?) * * +8: CLUT block * +0 - 3 CLUT block length * +4,5 (unknown) * +6,7 (unknown) * +8,9 number of colors? * +10,11 number of color groups? * +12... color data * 2bytes per color: * (bit14-10:blue, 9-5:green, 4-0:red) * * +8+12+n*(2or3): Pixel block * +0 - 3 Pixel block length * +4,5 x-offset? * +6,7 y-offset? * +8,9 image width (unit short) * +10,11 image height * +12... pixel data * */ typedef struct _TIM_BLOCK_INFO { long len; /* Block length (byte) */ short x, y; short w, h; } TIM_BLOCK_INFO; int read_tim_block_info(fp, p) FILE *fp; TIM_BLOCK_INFO *p; { p->len = readlelong(fp); p->x = readleshort(fp); p->y = readleshort(fp); p->w = readleshort(fp); p->h = readleshort(fp); message(" len = %ld, x = %d, y = %d, w = %d, h = %d\n", p->len, p->x, p->y, p->w, p->h); if (debug_mode) fprintf(stderr, " len = %ld, x = %d, y = %d, w = %d, h = %d\n", p->len, p->x, p->y, p->w, p->h); return 0; } /* read CLUT block */ int read_clut(fp) FILE *fp; { int i, n, c; TIM_BLOCK_INFO info; COL *cp; read_tim_block_info(fp, &info); free_color_all(); colposx = info.x; colposy = info.y; colfilew = info.w; colfileh = info.h; n = (info.len - 12) / 2; /* number of colors */ cp = color_buf; for (i = 0; i < n; i++) { c = readleshort(fp); if (i < 256) { cp->rgb.red = (c & 0x1f) << 3; cp->rgb.green = ((c >> 5) & 0x1f) << 3; cp->rgb.blue = ((c >> 10) & 0x1f) << 3; cp++; } } if (i > 256) i = 256; get_color(color_buf, i); get_requested_colors(); return 0; } /* read TIM file */ int rd_tim(fp) FILE *fp; { int c; int clut; /* bytes per color */ int bpp; /* bytes per pixel (0:4bit) */ int x, y, w, h; long l; TIM_BLOCK_INFO info; unsigned char lnbuf[1024]; /* skip magic number */ l = readlelong(fp); message("\nLoad TIM file.\n"); message(" magic number = 0x%08lx\n", l); if (debug_mode) fprintf(stderr, " magic number = 0x%08lx\n", l); /* read header */ l = readlelong(fp); c = l; bpp = c & 3; clut = (c >> 2) & 3; message(" mode = %08lx (bpp = %d, clut = %d)\n", l, bpp, clut); if (debug_mode) fprintf(stderr, " mode = %08lx (bpp = %d, clut = %d)\n", l, bpp, clut); if (clut) read_clut(fp); /* read pixel block */ read_tim_block_info(fp, &info); imgposx = info.x; imgposy = info.y; w = info.w; h = info.h; for (y = 0; y < h; y++) { if (y >= imgmaxh) break; fread(lnbuf, 1, w*2, fp); switch (bpp) { case 0: /* 1/2 byte per pixel */ for (x = 0; x < w*2; x++) { imgdata[y*imgmaxw+x*2] = lnbuf[x] & 0x0f; imgdata[y*imgmaxw+x*2+1] = lnbuf[x] >> 4; } break; case 1: /* 1 byte per pixel */ memcpy(imgdata+y*imgmaxw, lnbuf, w*2); break; default: /* other depth */ message("!\nNot supported pixel depth!\n"); return 1; } } /* calc true image width */ switch (bpp) { case 0: /* 1/2 byte per pixel */ w *= 4; imgfiledepth = 4; break; case 1: /* 1 byte per pixel */ w *= 2; imgfiledepth = 8; break; default: /* other depth */ message("!\nNot supported pixel depth!\n"); return 1; } imgupdate(w, h); return 0; } /* write TIM file */ int wr_tim(fp) FILE *fp; { long l; int i, x, y; COL *cp; char *p; char buf[1024]; setlelong(buf, 0x10L); if (imgfiledepth < 0) return 1; if (!imgfiledepth) imgfiledepth = 4; if (imgfiledepth <= 4) l = 0; else if (imgfiledepth <= 8) l = 1; else return 1; l |= 8; /* 2 bytes per color */ setlelong(buf+4, l); if (!fwrite(buf, 8, 1, fp)) return 1; /* header write error! */ /* colors */ l = 4 + 2 + 2 + 2 + 2 + colfilew * colfileh * 2; setlelong(buf, l); setleshort(buf+4, colposx); setleshort(buf+6, colposy); setleshort(buf+8, colfilew); setleshort(buf+10, colfileh); if (!fwrite(buf, 12, 1, fp)) return 1; /* clut block header write error! */ cp = color_buf; for (y = 0; y < colfileh; y++) { for (x = 0; x < colfilew; x++) { l = (cp->rgb.red >> 3) | ((cp->rgb.green >> 3) << 5) | ((cp->rgb.blue >> 3) << 10); cp++; setleshort(buf+x*2, (int)l); } if (!fwrite(buf, colfilew*2, 1, fp)) return 1; /* color data write error! */ } /* pixel block */ /* get width short count */ i = (imgfiledepth == 4) ? imgfilew/4 : imgfilew/2; l = 4 + 2 + 2 + 2 + 2 + i * 2 * imgfileh; setlelong(buf, l); setleshort(buf+4, imgposx); setleshort(buf+6, imgposy); setleshort(buf+8, i); setleshort(buf+10, imgfileh); if (!fwrite(buf, 12, 1, fp)) return 1; /* pixel block header write error! */ if (imgfiledepth == 4) { for (y = 0; y < imgfileh; y++) { p = buf; for (x = 0; x < i; x++) { *p++ = imgdata[y*imgmaxw+x*4+0] + (imgdata[y*imgmaxw+x*4+1]<<4); *p++ = imgdata[y*imgmaxw+x*4+2] + (imgdata[y*imgmaxw+x*4+3]<<4); } if (!fwrite(buf, i*2, 1, fp)) return 1; /* pixel write error! */ } } else { for (y = 0; y < imgfileh; y++) { if (!fwrite(imgdata+y*imgmaxw, i*2, 1, fp)) return 1; /* pixel write error! */ } } return 0; } /* read CLS file */ int rd_cls(fp) FILE *fp; { long l; int c, bpp, clut; l = readlelong(fp); message("\nLoad CLS file.\n"); message(" magic number = 0x%08lx\n", l); if (debug_mode) fprintf(stderr, " magic number = 0x%08lx\n", l); /* read header */ l = readlelong(fp); c = l; bpp = c & 3; clut = (c >> 2) & 3; message(" mode = %08lx (bpp = %d, clut = %d)\n", l, bpp, clut); if (debug_mode) fprintf(stderr, " mode = %08lx (bpp = %d, clut = %d)\n", l, bpp, clut); read_clut(fp); return 0; } /* End of file */