1 #include "Draw.h"
2 
3 namespace Upp {
4 
Info()5 Raster::Info::Info()
6 {
7 	bpp = 24;
8 	colors = 1 << 24;
9 	dots = Size(0, 0);
10 	hotspot = Point(0, 0);
11 	kind = IMAGE_OPAQUE;
12 	orientation = FLIP_NONE;
13 }
14 
GetFormat()15 const RasterFormat *Raster::GetFormat()
16 {
17 	return NULL;
18 }
19 
SeekPage(int page)20 void Raster::SeekPage(int page)
21 {
22 	ASSERT(page == 0);
23 }
24 
GetActivePage() const25 int Raster::GetActivePage() const
26 {
27 	return 0;
28 }
29 
GetPageCount()30 int Raster::GetPageCount()
31 {
32 	return 1;
33 }
34 
GetPageAspect(int page)35 int Raster::GetPageAspect(int page)
36 {
37 	return 0;
38 }
39 
GetPageDelay(int page)40 int Raster::GetPageDelay(int page)
41 {
42 	return 0;
43 }
44 
GetPageRect(int n)45 Rect Raster::GetPageRect(int n)
46 {
47 	Size sz = GetSize();
48 	return Rect(0, 0, sz.cx, sz.cy);
49 }
50 
GetPageDisposal(int n)51 int Raster::GetPageDisposal(int n)
52 {
53 	return 0;
54 }
55 
Pick(Line && b)56 void Raster::Line::Pick(Line&& b)
57 {
58 	data = b.data;
59 	fmtdata = b.fmtdata;
60 	raster = b.raster;
61 	free = b.free;
62 	fmtfree = b.fmtfree;
63 	const_cast<Line *>(&b)->free = const_cast<Line *>(&b)->fmtfree = false;
64 #ifdef _DEBUG
65 	const_cast<Line *>(&b)->data = NULL;
66 	const_cast<Line *>(&b)->fmtdata = NULL;
67 #endif
68 }
69 
MakeRGBA() const70 void Raster::Line::MakeRGBA() const
71 {
72 	ASSERT(fmtdata && raster);
73 	int cx = raster->GetWidth();
74 	const RasterFormat *f = raster->GetFormat();
75 	if(f) {
76 		RGBA *rgba = new RGBA[cx];
77 		free = true;
78 		f->Read(rgba, fmtdata, cx, raster->GetPalette());
79 		data = rgba;
80 	}
81 	else
82 		data = (const RGBA *)fmtdata;
83 }
84 
GetInfo()85 Raster::Info Raster::GetInfo()
86 {
87 	Info f;
88 	f.bpp = 32;
89 	f.colors = 256*256*256;
90 	f.dots = Size(0, 0);
91 	f.hotspot = Point(0, 0);
92 	f.kind = IMAGE_ALPHA;
93 	return f;
94 }
95 
Create()96 bool Raster::Create() { return true; }
97 
IsError()98 bool Raster::IsError() { return false; }
99 
GetPaletteCount()100 int   Raster::GetPaletteCount() { return 0; }
101 
GetPalette()102 const RGBA *Raster::GetPalette() { return NULL; }
103 
GetImage(int x,int y,int cx,int cy,const Gate<int,int> progress)104 Image Raster::GetImage(int x, int y, int cx, int cy, const Gate<int, int> progress)
105 {
106 	Size size = GetSize();
107 	y = minmax(y, 0, size.cy);
108 	int yy = minmax(y + cy, y, size.cy);
109 	x = minmax(x, 0, size.cx);
110 	cx = minmax(x + cx, x, size.cx) - x;
111 	ImageBuffer b(cx, yy - y);
112 	RGBA* t = b;
113 	int y0 = y;
114 	while(y < yy) {
115 		if(progress(y - y0, yy - y0))
116 			return Null;
117 		memcpy_t(t, ~GetLine(y) + x, cx);
118 		t += cx;
119 		y++;
120 	}
121 	Info f = GetInfo();
122 	b.SetHotSpot(f.hotspot - Point(x, y0));
123 	if(size.cx && size.cy)
124 		b.SetDots(Size(f.dots.cx * cx / size.cx, f.dots.cy * cy / size.cy));
125 	b.SetKind(f.kind);
126 
127 	if(IsError())
128 		return Image();
129 
130 	Image img = b;
131 	return FlipImage(img, f.orientation);
132 }
133 
GetImage(const Gate<int,int> progress)134 Image Raster::GetImage(const Gate<int, int> progress)
135 {
136 	Size sz = GetSize();
137 	return GetImage(0, 0, sz.cx, sz.cy, progress);
138 }
139 
~Raster()140 Raster::~Raster() {}
141 
GetLine(int line)142 Raster::Line ImageRaster::GetLine(int line)
143 {
144 	return Line(img[line], false);
145 }
146 
GetSize()147 Size ImageRaster::GetSize()
148 {
149 	return img.GetSize();
150 }
151 
GetInfo()152 Raster::Info ImageRaster::GetInfo()
153 {
154 	Raster::Info f = Raster::GetInfo();
155 	f.dots = img.GetDots();
156 	f.hotspot = img.GetHotSpot();
157 	f.kind = img.GetKind();
158 	return f;
159 }
160 
MemoryRaster()161 MemoryRaster::MemoryRaster()
162 : size(0, 0)
163 {
164 }
165 
Load(Raster & raster)166 void MemoryRaster::Load(Raster& raster)
167 {
168 	info = raster.GetInfo();
169 	size = raster.GetSize();
170 	palette.SetCount(raster.GetPaletteCount());
171 	if(!palette.IsEmpty())
172 		memcpy_t(palette.begin(), raster.GetPalette(), palette.GetCount());
173 	lines.SetCount(size.cy);
174 	if(const RasterFormat *fmt = raster.GetFormat()) {
175 		format = *fmt;
176 		int rowbytes = format.GetByteCount(size.cx);
177 		for(int i = 0; i < size.cy; i++) {
178 			lines[i].Alloc(rowbytes);
179 			memcpy_t(~lines[i], raster.GetLine(i).GetRawData(), rowbytes);
180 		}
181 	}
182 	else {
183 		format.SetRGBA();
184 		int rowbytes = sizeof(RGBA) * size.cx;
185 		for(int i = 0; i < size.cy; i++) {
186 			lines[i].Alloc(rowbytes);
187 			memcpy_t((RGBA *)~lines[i], raster.GetLine(i).GetRGBA(), rowbytes);
188 		}
189 	}
190 }
191 
GetLine(int line)192 Raster::Line MemoryRaster::GetLine(int line)
193 {
194 	if(format.IsRGBA())
195 		return Line((const RGBA *)~lines[line], false);
196 	else
197 		return Line(~lines[line], this, false);
198 }
199 
GetLength() const200 int MemoryRaster::GetLength() const
201 {
202 	return size.cy * (format.IsRGBA()
203 		? size.cx * sizeof(RGBA)
204 		: ((size.cx * info.bpp + 31) >> 5) * 4);
205 }
206 
Open(Stream & _s)207 bool StreamRaster::Open(Stream& _s)
208 {
209 	s = &_s;
210 	error = !Create();
211 	return !error;
212 }
213 
IsError()214 bool StreamRaster::IsError()
215 {
216 	return error || !s || s->IsError();
217 }
218 
Load(Stream & s,const Gate<int,int> progress)219 Image StreamRaster::Load(Stream& s, const Gate<int, int> progress)
220 {
221 	if(Open(s)) {
222 		Image img = GetImage(progress);
223 		if(!IsError())
224 			return img;
225 	}
226 	return Image();
227 }
228 
LoadFile(const char * fn,const Gate<int,int> progress)229 Image StreamRaster::LoadFile(const char *fn, const Gate<int, int> progress)
230 {
231 	FileIn in(fn);
232 	return in ? Load(in, progress) : Image();
233 }
234 
LoadString(const String & s,const Gate<int,int> progress)235 Image StreamRaster::LoadString(const String& s, const Gate<int, int> progress)
236 {
237 	StringStream ss(s);
238 	return Load(ss, progress);
239 }
240 
241 static StaticCriticalSection sAnyRaster;
242 
Map()243 Vector<void *>& StreamRaster::Map()
244 {
245 	static Vector<void *> x;
246 	return x;
247 }
248 
AddFormat(RasterFactory factory)249 void StreamRaster::AddFormat(RasterFactory factory)
250 {
251 	INTERLOCKED_(sAnyRaster)
252 		Map().Add((void *)factory);
253 }
254 
OpenAny(Stream & s)255 One<StreamRaster> StreamRaster::OpenAny(Stream& s)
256 {
257 	INTERLOCKED_(sAnyRaster)
258 		for(int i = 0; i < Map().GetCount(); i++) {
259 			int64 p = s.GetPos();
260 			One<StreamRaster> raster = (*RasterFactory(Map()[i]))();
261 			s.ClearError();
262 			if(raster->Open(s))
263 				return raster;
264 			s.ClearError();
265 			s.Seek(p);
266 		}
267 	return NULL;
268 }
269 
LoadAny(Stream & s,Gate<int,int> progress)270 Image StreamRaster::LoadAny(Stream& s, Gate<int, int> progress)
271 {
272 	One<StreamRaster> r = OpenAny(s);
273 	return r ? r->GetImage(progress) : Image();
274 }
275 
LoadFileAny(const char * fn,Gate<int,int> progress)276 Image StreamRaster::LoadFileAny(const char *fn, Gate<int, int> progress)
277 {
278 	FileIn in(fn);
279 	return LoadAny(in, progress);
280 }
281 
LoadStringAny(const String & s,Gate<int,int> progress)282 Image StreamRaster::LoadStringAny(const String& s, Gate<int, int> progress)
283 {
284 	StringStream ss(s);
285 	return LoadAny(ss, progress);
286 }
287 
288 }
289