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