#include "Draw.h" NAMESPACE_UPP Raster::Info::Info() { bpp = 24; colors = 1 << 24; dots = Size(0, 0); hotspot = Point(0, 0); kind = IMAGE_OPAQUE; } const RasterFormat *Raster::GetFormat() { return NULL; } void Raster::SeekPage(int page) { ASSERT(page == 0); } int Raster::GetActivePage() const { return 0; } int Raster::GetPageCount() { return 1; } int Raster::GetPageAspect(int page) { return 0; } int Raster::GetPageDelay(int page) { return 0; } Rect Raster::GetPageRect(int n) { Size sz = GetSize(); return Rect(0, 0, sz.cx, sz.cy); } int Raster::GetPageDisposal(int n) { return 0; } void Raster::Line::Pick(Line rval_ b) { data = b.data; fmtdata = b.fmtdata; raster = b.raster; free = b.free; fmtfree = b.fmtfree; const_cast(&b)->free = const_cast(&b)->fmtfree = false; #ifdef _DEBUG const_cast(&b)->data = NULL; const_cast(&b)->fmtdata = NULL; #endif } void Raster::Line::MakeRGBA() const { ASSERT(fmtdata && raster); int cx = raster->GetWidth(); const RasterFormat *f = raster->GetFormat(); if(f) { RGBA *rgba = new RGBA[cx]; free = true; f->Read(rgba, fmtdata, cx, raster->GetPalette()); data = rgba; } else data = (const RGBA *)fmtdata; } Raster::Info Raster::GetInfo() { Info f; f.bpp = 32; f.colors = 256*256*256; f.dots = Size(0, 0); f.hotspot = Point(0, 0); f.kind = IMAGE_ALPHA; return f; } bool Raster::Create() { return true; } bool Raster::IsError() { return false; } int Raster::GetPaletteCount() { return 0; } const RGBA *Raster::GetPalette() { return NULL; } Image Raster::GetImage(int x, int y, int cx, int cy, const Gate2 progress) { Size size = GetSize(); y = minmax(y, 0, size.cy); int yy = minmax(y + cy, y, size.cy); x = minmax(x, 0, size.cx); cx = minmax(x + cx, x, size.cx) - x; ImageBuffer b(cx, yy - y); RGBA* t = b; int y0 = y; while(y < yy) { if(progress(y - y0, yy - y0)) return Null; memcpy(t, ~GetLine(y) + x, cx * sizeof(RGBA)); t += cx; y++; } Info f = GetInfo(); b.SetHotSpot(f.hotspot - Point(x, y0)); if(size.cx && size.cy) b.SetDots(Size(f.dots.cx * cx / size.cx, f.dots.cy * cy / size.cy)); return IsError() ? Image() : Image(b); } Image Raster::GetImage(const Gate2 progress) { Size sz = GetSize(); return GetImage(0, 0, sz.cx, sz.cy, progress); } Raster::~Raster() {} Raster::Line ImageRaster::GetLine(int line) { return Line(img[line], false); } Size ImageRaster::GetSize() { return img.GetSize(); } Raster::Info ImageRaster::GetInfo() { Raster::Info f = Raster::GetInfo(); f.dots = img.GetDots(); f.hotspot = img.GetHotSpot(); f.kind = img.GetKind(); return f; } MemoryRaster::MemoryRaster() : size(0, 0) { } void MemoryRaster::Load(Raster& raster) { info = raster.GetInfo(); size = raster.GetSize(); palette.SetCount(raster.GetPaletteCount()); if(!palette.IsEmpty()) memcpy(palette, raster.GetPalette(), palette.GetCount() * sizeof(RGBA)); lines.SetCount(size.cy); if(const RasterFormat *fmt = raster.GetFormat()) { format = *fmt; int rowbytes = format.GetByteCount(size.cx); for(int i = 0; i < size.cy; i++) { lines[i].Alloc(rowbytes); memcpy(~lines[i], raster.GetLine(i).GetRawData(), rowbytes); } } else { format.SetRGBA(); int rowbytes = sizeof(RGBA) * size.cx; for(int i = 0; i < size.cy; i++) { lines[i].Alloc(rowbytes); memcpy(~lines[i], raster.GetLine(i).GetRGBA(), rowbytes); } } } Raster::Line MemoryRaster::GetLine(int line) { if(format.IsRGBA()) return Line((const RGBA *)~lines[line], false); else return Line(~lines[line], this, false); } int MemoryRaster::GetLength() const { return size.cy * (format.IsRGBA() ? size.cx * sizeof(RGBA) : ((size.cx * info.bpp + 31) >> 5) * 4); } bool StreamRaster::Open(Stream& _s) { s = &_s; error = !Create(); return !error; } bool StreamRaster::IsError() { return error || !s || s->IsError(); } Image StreamRaster::Load(Stream& s, const Gate2 progress) { if(Open(s)) { Image img = GetImage(progress); if(!IsError()) return img; } return Image(); } Image StreamRaster::LoadFile(const char *fn, const Gate2 progress) { FileIn in(fn); return in ? Load(in, progress) : Image(); } Image StreamRaster::LoadString(const String& s, const Gate2 progress) { StringStream ss(s); return Load(ss, progress); } static StaticCriticalSection sAnyRaster; Vector& StreamRaster::Map() { static Vector x; return x; } void StreamRaster::AddFormat(RasterFactory factory) { INTERLOCKED_(sAnyRaster) Map().Add((void *)factory); } One StreamRaster::OpenAny(Stream& s) { INTERLOCKED_(sAnyRaster) for(int i = 0; i < Map().GetCount(); i++) { int64 p = s.GetPos(); One raster = (*RasterFactory(Map()[i]))(); s.ClearError(); if(raster->Open(s)) return raster; s.ClearError(); s.Seek(p); } return NULL; } Image StreamRaster::LoadAny(Stream& s, const Gate2 progress) { One r = OpenAny(s); return r ? r->GetImage(progress) : Image(); } Image StreamRaster::LoadFileAny(const char *fn, const Gate2 progress) { FileIn in(fn); return LoadAny(in, progress); } Image StreamRaster::LoadStringAny(const String& s, const Gate2 progress) { StringStream ss(s); return LoadAny(ss, progress); } END_UPP_NAMESPACE