///////////////////////////////////////////////////////////////////////////// // // This file is Copyright 1992,1993 by Warwick W. Allison. // This file is part of the gem++ library. // You are free to copy and modify these sources, provided you acknowledge // the origin by retaining this notice, and adhere to the conditions // described in the file COPYING.LIB. // ///////////////////////////////////////////////////////////////////////////// #include "img.h" #include #include #define SEEK_CUR 1 inline int Bpad(int x) { return (x+7)>>3; } static void readIMG(unsigned char*,int patlen,int bW,int H,FILE*); struct IMGfileheader { short version; short length; short planes; short patternlen; short uW,uH; short W,H; }; IMG::IMG(int w,int h,int d) : W(w), H(h), D(d), bW(Bpad(w)), uW(85), uH(85), data(new unsigned char[H*bW]), Cursor(0), bit(TOPBIT), External(FALSE) { } IMG::IMG(unsigned char* At,int w,int h,int d) : W(w), H(h), D(d), bW(Bpad(w)), uW(85), uH(85), data(At), Cursor(0), bit(TOPBIT), External(TRUE) { } IMG::IMG(const char *fn) : Cursor(0), data(0), bit(TOPBIT), External(FALSE) { FILE *f=fopen(fn,"rb"); if (!f) return; IMGfileheader header; fread(&header,sizeof(header),1,f); if (header.length*sizeof(short)!=sizeof(header)) fseek(f,header.length*sizeof(short)-sizeof(header),SEEK_CUR); W=header.W; H=header.H; D=header.planes; bW=Bpad(W); uW=header.uW; uH=header.uH; data=new unsigned char[H*bW]; readIMG(data,header.patternlen,bW,uH,f); fclose(f); } IMG::~IMG() { if (!External) delete data; } static void readIMG(unsigned char* bitmap,int patlen,int bW,int H,FILE* f) { int c; int linerep=0; int thisln=bW; while (EOF!=(c=fgetc(f))) { switch (c) { case 0: int n; if (EOF!=(n=fgetc(f))) { if (n) { // Repeating pattern fread(bitmap,patlen,1,f); bitmap+=patlen; thisln-=patlen; while (--n) { unsigned char *from=bitmap-patlen; for (int pn=patlen; pn; pn--) *bitmap++=*from++; thisln-=patlen; } } else { // Next scanline repeats n=fgetc(f); // Should be 0xff n=fgetc(f); linerep+=n-1; // REPEATs, not total number } } break; case 0x80: // Literal int nl; if (EOF!=(nl=fgetc(f))) { fread(bitmap,nl,1,f); bitmap+=nl; thisln-=nl; } break; default: // Solid run unsigned char pat=((c&0x80) ? 0xff : 0); int nsol=c&0x7f; thisln-=nsol; while (nsol--) *bitmap++=pat; } while (thisln<=0) { thisln+=bW; H--; while (linerep) { unsigned char *from=bitmap-bW; for (int lineb=0; lineb