enum { RASTER_1, RASTER_2, RASTER_4, RASTER_8, RASTER_8ALPHA, RASTER_16, RASTER_24, RASTER_32, RASTER_32ALPHA, RASTER_32PREMULTIPLIED, RASTER_MSBFIRST = 0x80, RASTER_MAP_R = 32, RASTER_SHIFT_R = 3, RASTER_MAP_G = 64, RASTER_SHIFT_G = 2, RASTER_MAP_B = 16, RASTER_SHIFT_B = 4, RASTER_MAP_MAX = 64 }; struct PaletteCv { Buffer cv; byte *At(int r, int b) { return cv + (r << 10) + (b << 6); } byte Get(const RGBA& b) const { return cv[(int(b.r >> RASTER_SHIFT_R) << 10) + (int(b.g >> RASTER_SHIFT_G)) + (int(b.b >> RASTER_SHIFT_B) << 6)]; } PaletteCv() { cv.Alloc(RASTER_MAP_R * RASTER_MAP_G * RASTER_MAP_B); } }; class RasterFormat { byte type; dword rmask, gmask, bmask, amask; byte rpos, gpos, bpos, apos; static void TailBits(RGBA *t, const byte *src, int cx, byte andm, byte shift, const RGBA *palette); static void TailBitsMSB1st(RGBA *t, const byte *src, int cx, byte shift1, byte andm, byte shift, const RGBA *palette); public: void Set1lf() { type = RASTER_1; } void Set1mf() { type = RASTER_1|RASTER_MSBFIRST; } void Set2lf() { type = RASTER_2; } void Set2mf() { type = RASTER_2|RASTER_MSBFIRST; } void Set4lf() { type = RASTER_4; } void Set4mf() { type = RASTER_4|RASTER_MSBFIRST; } void Set8() { type = RASTER_8; } void Set8A() { type = RASTER_8ALPHA; } void Set16le(dword rmask, dword gmask, dword bmask); void Set16be(dword rmask, dword gmask, dword bmask); void Set24le(dword rmask, dword gmask, dword bmask); void Set24be(dword rmask, dword gmask, dword bmask); void Set32le(dword rmask, dword gmask, dword bmask, dword amask = 0); void Set32be(dword rmask, dword gmask, dword bmask, dword amask = 0); void Set32leStraight(dword rmask, dword gmask, dword bmask, dword amask); void Set32beStraight(dword rmask, dword gmask, dword bmask, dword amask); void SetRGBA(); void SetRGBAStraight(); int GetType() const { return type; } int IsRGBA() const; int GetByteCount(int cx) const; int GetBpp() const; bool HasAlpha() const; int GetColorCount() const; int GetPaletteCount() const; void Read(RGBA *t, const byte *s, int cx, const RGBA *palette) const; void Write(byte *t, const RGBA *s, int cx, const PaletteCv *palcv) const; }; class Raster { public: class Line { mutable const RGBA *data; const byte *fmtdata; Raster *raster; mutable bool free; bool fmtfree; friend class Raster; void MakeRGBA() const; void Free() { if(free) delete[] data; if(fmtfree) delete[] fmtdata; } void Pick(pick_ Line& b); public: const RGBA *GetRGBA() const { if(!data) MakeRGBA(); return data; } const byte *GetRawData() const { return fmtdata; } operator const RGBA *() const { return GetRGBA(); } const RGBA *operator~() const { return GetRGBA(); } Line(const RGBA *data, bool free) : data(data), fmtdata((byte *)data), raster(NULL), free(free), fmtfree(false) {} Line(const byte *fmtdata, Raster *raster, bool fmtfree) : data(NULL), fmtdata(fmtdata), raster(raster), free(false), fmtfree(fmtfree) {} Line(pick_ Line& b) { Pick(b); } Line() { data = NULL; fmtdata = NULL; raster = NULL; free = fmtfree = false; } ~Line() { Free(); } void operator=(pick_ Line& b) { Free(); Pick(b); } }; struct Info { int bpp; int colors; Size dots; Point hotspot; int kind; Info(); }; public: virtual void SeekPage(int page); virtual int GetActivePage() const; virtual int GetPageCount(); virtual bool Create(); virtual Size GetSize() = 0; virtual Info GetInfo(); virtual Line GetLine(int line) = 0; virtual bool IsError(); virtual int GetPaletteCount(); virtual const RGBA *GetPalette(); virtual const RasterFormat *GetFormat(); int GetWidth() { return GetSize().cx; } int GetHeight() { return GetSize().cy; } Line operator[](int i) { return GetLine(i); } Image GetImage(int x, int y, int cx, int cy, const Gate2 progress = false); Image GetImage(const Gate2 progress = false); virtual ~Raster(); }; typedef Raster::Line RasterLine; typedef Raster::Info RasterInfo; void CreatePaletteCv(const RGBA *palette, int ncolors, PaletteCv& cv_pal); void CreatePalette(Raster& raster, RGBA *palette, int ncolors); void CreatePalette(Raster& raster, RGBA *palette, int ncolors, PaletteCv& cv); class ImageRaster : public Raster { Image img; public: virtual Size GetSize(); virtual Line GetLine(int line); virtual Info GetInfo(); ImageRaster(const Image& img) : img(img) {} }; class MemoryRaster : public Raster { RasterFormat format; Info info; Size size; Vector< Buffer > lines; Vector palette; public: virtual Size GetSize() { return size; } virtual Info GetInfo() { return info; } virtual Line GetLine(int line); virtual int GetPaletteCount() { return palette.GetCount(); } virtual const RGBA *GetPalette() { return palette.Begin(); } virtual const RasterFormat *GetFormat() { return &format; } void Load(Raster& raster); int GetLength() const; MemoryRaster(); MemoryRaster(Raster& raster) { Load(raster); } }; class StreamRaster : public Raster { Stream *s; bool error; typedef StreamRaster *(*RasterFactory)(); template static StreamRaster *FactoryFn() { return new T; } static void AddFormat(RasterFactory f); static Vector& Map(); public: Stream& GetStream() { return *s; } bool Open(Stream& _s); bool IsError(); void SetError() { error = true; } Image Load(Stream& s, const Gate2 progress = false); Image LoadFile(const char *fn, const Gate2 progress = false); Image LoadString(const String& s, const Gate2 progress = false); template static void Register() { AddFormat(&StreamRaster::FactoryFn); } static One OpenAny(Stream& s); static Image LoadAny(Stream& s, const Gate2 progress = false); static Image LoadFileAny(const char *fn, const Gate2 progress = false); static Image LoadStringAny(const String& s, const Gate2 progress = false); StreamRaster() { error = true; } }; class RasterEncoder { Size size, dots; Point hotspot; RGBA *line; Buffer scanline; int line_bytes; Buffer h; Buffer palette; One palette_cv; RGBA *Pal(); protected: RasterFormat format; void SetLine(RGBA *_line); public: virtual int GetPaletteCount(); virtual void Start(Size sz) = 0; virtual void WriteLineRaw(const byte *data) = 0; void WriteLine(); void WriteLine(const RGBA *s); const RasterFormat& GetFormat() const { return format; } const RGBA *GetPalette(); const PaletteCv *GetPaletteCv() { return ~palette_cv; } operator RGBA *() { return line; } RGBA *operator~() { return line; } Size GetSize() const { return size; } int GetWidth() const { return GetSize().cx; } int GetHeight() const { return GetSize().cy; } void SetHotSpot(Point p) { hotspot = p; } Point GetHotSpot() const { return hotspot; } void SetDots(Size _dots) { dots = _dots; } Size GetDots() const { return dots; } void SetPalette(const RGBA *palette); void SetPalette(Raster& pal_raster); void Create(Size sz); void Create(int cx, int cy) { Create(Size(cx, cy)); } void Create(Size sz, const RGBA *palette); void Create(int cx, int cy, const RGBA *palette); void Create(Size sz, Raster& pal_raster); void Create(int cx, int cy, Raster& pal_raster); RasterEncoder(); virtual ~RasterEncoder(); }; class ImageEncoder : public RasterEncoder { int ii; ImageBuffer ib; public: virtual void Start(Size sz); virtual void WriteLineRaw(const byte *data); operator const RGBA *() { return Image(ib); } operator Image() { return Image(ib); } }; class StreamRasterEncoder : public RasterEncoder { Stream *s; public: Stream& GetStream() { return *s; } void SetStream(Stream& _s) { s = &_s; } void Save(Stream& s, Raster& raster); bool SaveFile(const char *fn, Raster& raster); String SaveString(Raster& raster); void Save(Stream& s, const Image& img); bool SaveFile(const char *fn, const Image& img); String SaveString(const Image& img); };