#include "ET++.ph" #include "Converter.h" #include "Class.h" #include "Data.h" #include "Bitmap.h" #include "DevBitmap.h" #include "String.h" #include "TypeMatcher.h" #include "ET_stdio.h" static const Symbol cDocTypeSunBitmap("SUNBITMAP"); static TypeMatcher matcher(cDocTypeSunBitmap, "icon", "/* Format_version=1", TRUE); //---- SunIconConverter -------------------------------------------------------- class SunIconConverter : public Converter { public: MetaDef(SunIconConverter); SunIconConverter() { } const char *AsString() { return "Sun Icon"; } Object *DoConvert1(FILE *fp); Object *Convert(Data *data, Class *want); bool CanConvert(Data *data, Class *want) { return data->Type() == cDocTypeSunBitmap && want == Meta(Bitmap); } }; NewMetaImpl0(SunIconConverter,Converter); Object *SunIconConverter::DoConvert1(FILE *fp) { int tmp, version= 1, width= 0, height= 0, depth= 1, bitsperitem= 16; int b, x= 0, y= 0, bytesperline, bytesperitem, itemsperline, imbytesperline; u_long mask, m, d; char buf[200], c; Bitmap *BM; DevBitmap *dbm; while (fscanf(fp, "%s", buf) == 1) { if (sscanf(buf, "Format_version=%d", &version) == 1) continue; if (sscanf(buf, "Width=%d", &width) == 1) continue; if (sscanf(buf, "Height=%d", &height) == 1) continue; if (sscanf(buf, "Depth=%d", &depth) == 1) continue; if (sscanf(buf, "Valid_bits_per_item=%d", &bitsperitem) == 1) continue; if (strcmp(buf, "*/") == 0) break; } if (width <= 0 || height <= 0) return 0; BM= new Bitmap(Point(width, height), depth); dbm= BM->GetDevBitmap(); itemsperline= (width-1) / bitsperitem + 1; bytesperitem= bitsperitem / 8; bytesperline= itemsperline * bytesperitem; mask= 0xff << (bytesperitem-1)*8; imbytesperline= dbm->BytesPerLine(); byte *bbuf= new byte[bytesperline], *bp= bbuf; BitmapInfo bi(BM->Size(), depth, 1); while (fscanf(fp, "%i%c", &tmp, &c) >= 1) { m= mask; for (b= bytesperitem-1; b >= 0; b--) { d= (tmp & m) >> (b*8); m >>= 8; if (x < imbytesperline && y < height) *bp++= (byte) d; x++; if (x == bytesperline) { dbm->SetRow(&bi, y++, bbuf); bp= bbuf; x= 0; } } } delete bbuf; return BM; } Object *SunIconConverter::Convert(Data *data, Class*) { FILE *fp; if (fp= fopen((char*) data->Name(), "r")) { Object *op= DoConvert1(fp); fclose(fp); if (op == 0) fprintf(stderr, "error\n"); return op; } return 0; }