source: oup/releases/0.31a/Unit6_imgfuncs.pas@ 455

Last change on this file since 455 was 34, checked in by alloc, 18 years ago
File size: 15.4 KB
RevLine 
[34]1UNIT Unit6_imgfuncs;
2INTERFACE
3USES Math, Dialogs, SysUtils, Unit3_data, Unit15_Classes;
4
5TYPE
6 TImgPackage=RECORD
7 imgx,imgy:Word;
8 imgdepth:Byte;
9 storetype:Byte;
10 datasize:LongWord;
11 raw_addr:LongWord;
12 imgdata:Tdata;
13 END;
14FUNCTION ResizeImage(oldx,oldy:LongWord; imgdepth:Byte; data:Tdata):Tdata;
15FUNCTION RevertImage(imgx,imgy,imgdepth:LongWord; imgdata:Tdata):Tdata;
16FUNCTION DecompressImage(imgx,imgy:LongWord; imgdata:Tdata):Tdata;
17FUNCTION ImgdataToBmp(imgx,imgy,imgdepth,storetype:LongWord; imgdata:Tdata):Tdata;
18FUNCTION BmpToImgdata(bmpdata:Tdata; _32bit:Boolean):TImgPackage;
19FUNCTION LoadTXMBconnected(fileid:LongWord):TImgPackage;
20FUNCTION LoadImgData(fileid:LongWord):TImgPackage;
21FUNCTION GetImageDataSize(imgx,imgy,imgdepth:Word; fading:Boolean):LongWord;
22FUNCTION CreateFadedImage(image:TImgPackage; VAR faded:Tdata):Boolean;
23
24IMPLEMENTATION
25USES Unit2_functions;
26
27
28FUNCTION ResizeImage(oldx,oldy:LongWord; imgdepth:Byte; data:Tdata):Tdata;
29 VAR
30 i,j:LongWord;
31 col,row,row_orig:LongWord;
32 temparray:Tdata;
33 BEGIN
34 SetLength(temparray,(oldx DIV 2)*(oldy DIV 2)*(imgdepth DIV 8));
35 row_orig:=0;
36 row:=0;
37 col:=0;
38 FOR i:=0 TO (oldx*oldy)-1 DO BEGIN
39 IF ((i MOD oldx)=0) AND (i>0) THEN BEGIN
40 Inc(row_orig);
41 IF (row_orig MOD 2)=0 THEN BEGIN
42 Inc(row);
43 col:=0;
44 END;
45 END;
46 IF (row_orig MOD 2)=0 THEN BEGIN
47 IF (i MOD 2)=0 THEN BEGIN
48 FOR j:=0 TO (imgdepth DIV 8)-1 DO
49 temparray[((row*(oldx DIV 2))+col)*(imgdepth DIV 8)+j]:=data[(i*(imgdepth DIV 8))+j];
50 Inc(col);
51 END;
52 END;
53 END;
54 Result:=temparray;
55 END;
56
57
58FUNCTION RevertImage(imgx,imgy,imgdepth:LongWord; imgdata:Tdata):Tdata;
59 VAR
60 x,y,i:LongWord;
61 BEGIN
62 SetLength(Result,imgx*imgy*(imgdepth DIV 8));
63 FOR y:=0 TO imgy-1 DO
64 FOR x:=0 TO imgx-1 DO
65 FOR i:=0 TO (imgdepth DIV 8)-1 DO
66 Result[((imgx*(imgy-1-y)+x)*(imgdepth DIV 8))+i]:=
67 imgdata[(imgx*y+x)*(imgdepth DIV 8)+i];
68 END;
69
70
71FUNCTION DecompressImage(imgx,imgy:LongWord; imgdata:Tdata):Tdata;
72 TYPE
73 Tcolor=RECORD
74 RGBb:Byte;
75 RGBg:Byte;
76 RGBr:Byte;
77 RGBa:Byte;
78 END;
79 VAR
80 i,j,x,y:LongWord;
81 color:Array[1..4] OF Tcolor;
82 pixel:Array[1..16] OF Byte;
83 BEGIN
84 x:=0;
85 y:=0;
86 SetLength(Result,imgx*imgy*4);
87 FOR i:=0 TO ((imgx*imgy) DIV 16)-1 DO BEGIN
88 Color[1].RGBb:=Floor(((imgdata[(i*8)+0]+imgdata[(i*8)+1]*256) AND $001F) / $001F * 255);
89 Color[1].RGBg:=Floor(((imgdata[(i*8)+0]+imgdata[(i*8)+1]*256) AND $07E0) / $07E0 * 255);
90 Color[1].RGBr:=Floor(((imgdata[(i*8)+0]+imgdata[(i*8)+1]*256) AND $F800) / $F800 * 255);
91 Color[1].RGBa:=255;
92 Color[2].RGBb:=Floor(((imgdata[(i*8)+2]+imgdata[(i*8)+3]*256) AND $001F) / $001F * 255);
93 Color[2].RGBg:=Floor(((imgdata[(i*8)+2]+imgdata[(i*8)+3]*256) AND $07E0) / $07E0 * 255);
94 Color[2].RGBr:=Floor(((imgdata[(i*8)+2]+imgdata[(i*8)+3]*256) AND $F800) / $F800 * 255);
95 Color[2].RGBa:=255;
96 Color[3].RGBb:=Floor( Color[1].RGBb/3*2 + Color[2].RGBb/3 );
97 Color[3].RGBg:=Floor( Color[1].RGBg/3*2 + Color[2].RGBg/3 );
98 Color[3].RGBr:=Floor( Color[1].RGBr/3*2 + Color[2].RGBr/3 );
99 Color[3].RGBa:=255;
100 Color[4].RGBb:=Floor( Color[1].RGBb/3 + Color[2].RGBb/3*2 );
101 Color[4].RGBg:=Floor( Color[1].RGBg/3 + Color[2].RGBg/3*2 );
102 Color[4].RGBr:=Floor( Color[1].RGBr/3 + Color[2].RGBr/3*2 );
103 Color[4].RGBa:=255;
104 Pixel[1]:=Floor( (imgdata[(i*8)+4] AND $C0) / $40 + 1 );
105 Pixel[2]:=Floor( (imgdata[(i*8)+4] AND $30) / $10 + 1 );
106 Pixel[3]:=Floor( (imgdata[(i*8)+4] AND $0C) / $04 + 1 );
107 Pixel[4]:=Floor( (imgdata[(i*8)+4] AND $03) + 1 );
108 Pixel[5]:=Floor( (imgdata[(i*8)+5] AND $C0) / $40 + 1 );
109 Pixel[6]:=Floor( (imgdata[(i*8)+5] AND $30) / $10 + 1 );
110 Pixel[7]:=Floor( (imgdata[(i*8)+5] AND $0C) / $04 + 1 );
111 Pixel[8]:=Floor( (imgdata[(i*8)+5] AND $03) + 1 );
112 Pixel[9]:=Floor( (imgdata[(i*8)+6] AND $C0) / $40 + 1 );
113 Pixel[10]:=Floor( (imgdata[(i*8)+6] AND $30) / $10 + 1 );
114 Pixel[11]:=Floor( (imgdata[(i*8)+6] AND $0C) / $04 + 1 );
115 Pixel[12]:=Floor( (imgdata[(i*8)+6] AND $03) + 1 );
116 Pixel[13]:=Floor( (imgdata[(i*8)+7] AND $C0) / $40 + 1 );
117 Pixel[14]:=Floor( (imgdata[(i*8)+7] AND $30) / $10 + 1 );
118 Pixel[15]:=Floor( (imgdata[(i*8)+7] AND $0C) / $04 + 1 );
119 Pixel[16]:=Floor( (imgdata[(i*8)+7] AND $03) + 1 );
120 FOR j:=0 TO 3 DO BEGIN
121 Result[((y+3)*imgx+x+j)*3+0]:=Color[Pixel[16-j]].RGBb;
122 Result[((y+3)*imgx+x+j)*3+1]:=Color[Pixel[16-j]].RGBg;
123 Result[((y+3)*imgx+x+j)*3+2]:=Color[Pixel[16-j]].RGBr;
124 END;
125 FOR j:=0 TO 3 DO BEGIN
126 Result[((y+2)*imgx+x+j)*3+0]:=Color[Pixel[12-j]].RGBb;
127 Result[((y+2)*imgx+x+j)*3+1]:=Color[Pixel[12-j]].RGBg;
128 Result[((y+2)*imgx+x+j)*3+2]:=Color[Pixel[12-j]].RGBr;
129 END;
130 FOR j:=0 TO 3 DO BEGIN
131 Result[((y+1)*imgx+x+j)*3+0]:=Color[Pixel[8-j]].RGBb;
132 Result[((y+1)*imgx+x+j)*3+1]:=Color[Pixel[8-j]].RGBg;
133 Result[((y+1)*imgx+x+j)*3+2]:=Color[Pixel[8-j]].RGBr;
134 END;
135 FOR j:=0 TO 3 DO BEGIN
136 Result[((y+0)*imgx+x+j)*3+0]:=Color[Pixel[4-j]].RGBb;
137 Result[((y+0)*imgx+x+j)*3+1]:=Color[Pixel[4-j]].RGBg;
138 Result[((y+0)*imgx+x+j)*3+2]:=Color[Pixel[4-j]].RGBr;
139 END;
140 x:=x+4;
141 IF x=imgx THEN BEGIN
142 y:=y+4;
143 x:=0;
144 END;
145 END;
146 END;
147
148
149FUNCTION ImgdataToBmp(imgx,imgy,imgdepth,storetype:LongWord; imgdata:Tdata):Tdata;
150 CONST BMPheader:Array[0..53] OF Byte=
151 ($42,$4D,0,0,0,0,0,0,0,0,54,0,0,0,
152 40,0,0,0,0,0,0,0,0,0,0,0,1,0,$18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
153 VAR
154 i,x,y:LongWord;
155 BEGIN
156 CASE storetype OF
157 0: BEGIN
158 SetLength(Result,imgx*imgy*3);
159 FOR y:=0 TO imgy-1 DO BEGIN
160 FOR x:=0 TO imgx-1 DO BEGIN
161 Result[((imgx*y+x)*3)+0]:=Floor( ( (imgdata[(imgx*y+x)*2]+imgdata[(imgx*y+x)*2+1]*256) AND $000F ) / $000F * 255);
162 Result[((imgx*y+x)*3)+1]:=Floor( ( (imgdata[(imgx*y+x)*2]+imgdata[(imgx*y+x)*2+1]*256) AND $00F0 ) / $00F0 * 255);
163 Result[((imgx*y+x)*3)+2]:=Floor( ( (imgdata[(imgx*y+x)*2]+imgdata[(imgx*y+x)*2+1]*256) AND $0F00 ) / $0F00 * 255);
164 END;
165 END;
166 END;
167 1,2: BEGIN
168 SetLength(Result,imgx*imgy*3);
169 FOR y:=0 TO imgy-1 DO BEGIN
170 FOR x:=0 TO imgx-1 DO BEGIN
171 Result[((imgx*y+x)*3)+0]:=Floor( ( (imgdata[(imgx*y+x)*2]+imgdata[(imgx*y+x)*2+1]*256) AND $001F ) / $001F * 255);
172 Result[((imgx*y+x)*3)+1]:=Floor( ( (imgdata[(imgx*y+x)*2]+imgdata[(imgx*y+x)*2+1]*256) AND $03E0 ) / $03E0 * 255);
173 Result[((imgx*y+x)*3)+2]:=Floor( ( (imgdata[(imgx*y+x)*2]+imgdata[(imgx*y+x)*2+1]*256) AND $7C00 ) / $7C00 * 255);
174 END;
175 END;
176 END;
177 8: BEGIN
178 SetLength(Result,imgx*imgy*3);
179 FOR y:=0 TO imgy-1 DO BEGIN
180 FOR x:=0 TO imgx-1 DO BEGIN
181 Result[((imgx*y+x)*3)+0]:=imgdata[(imgx*y+x)*4+0];
182 Result[((imgx*y+x)*3)+1]:=imgdata[(imgx*y+x)*4+1];
183 Result[((imgx*y+x)*3)+2]:=imgdata[(imgx*y+x)*4+2];
184 END;
185 END;
186 END;
187 9: BEGIN
188 Result:=DecompressImage(imgx,imgy,imgdata);
189 END;
190 END;
191 Result:=RevertImage(imgx,imgy,24,Result);
192 SetLength(Result,imgx*imgy*3+54);
193 FOR i:=High(Result)-54 DOWNTO 0 DO Result[i+54]:=Result[i];
194
195 FOR i:=0 TO High(BMPheader) DO Result[i]:=BMPheader[i];
196 Result[2]:=((imgx*imgy*3+54) AND $000000FF);
197 Result[3]:=((imgx*imgy*3+54) AND $0000FF00) DIV $100;
198 Result[4]:=((imgx*imgy*3+54) AND $00FF0000) DIV $10000;
199 Result[5]:=((imgx*imgy*3+54) AND $FF000000) DIV $1000000;
200 Result[18]:=(imgx AND $000000FF) DIV $1;
201 Result[19]:=(imgx AND $0000FF00) DIV $100;
202 Result[20]:=(imgx AND $00FF0000) DIV $10000;
203 Result[21]:=(imgx AND $FF000000) DIV $1000000;
204 Result[22]:=(imgy AND $000000FF) DIV $1;
205 Result[23]:=(imgy AND $0000FF00) DIV $100;
206 Result[24]:=(imgy AND $00FF0000) DIV $10000;
207 Result[25]:=(imgy AND $FF000000) DIV $1000000;
208 Result[34]:=((imgx*imgy*3) AND $000000FF) DIV $1;
209 Result[35]:=((imgx*imgy*3) AND $0000FF00) DIV $100;
210 Result[36]:=((imgx*imgy*3) AND $00FF0000) DIV $10000;
211 Result[37]:=((imgx*imgy*3) AND $FF000000) DIV $1000000;
212 END;
213
214FUNCTION BmpToImgdata(bmpdata:Tdata; _32bit:Boolean):TImgPackage;
215 VAR
216 x,y:LongWord;
217 r24,g24,b24:Word;
218 r16,g16,b16:Word;
219 gesamt:Word;
220 BEGIN
221 Result.imgdepth:=0;
222 IF NOT((bmpdata[00]=$42) AND (bmpdata[01]=$4D)) THEN BEGIN
223 ShowMessage('Not a standard 24bit bitmap');
224 Exit;
225 END;
226 IF NOT(bmpdata[10]=54) THEN BEGIN
227 ShowMessage('Imagedata has to start at 0x54');
228 Exit;
229 END;
230 IF NOT(bmpdata[14]=40) THEN BEGIN
231 ShowMessage('Second bitmap header has to have 40 bytes');
232 Exit;
233 END;
234 IF NOT(bmpdata[28]=24) THEN BEGIN
235 ShowMessage('Bitmap has to have 24bits');
236 Exit;
237 END;
238 IF NOT(bmpdata[30]=0) THEN BEGIN
239 ShowMessage('Bitmap has to be uncompressed');
240 Exit;
241 END;
242 Result.imgx:=bmpdata[18]+bmpdata[19]*256+bmpdata[20]*256*256+bmpdata[21]*256*256*256;
243 Result.imgy:=bmpdata[22]+bmpdata[23]*256+bmpdata[24]*256*256+bmpdata[25]*256*256*256;
244 IF _32bit THEN BEGIN
245 Result.imgdepth:=32;
246 Result.storetype:=8;
247 END ELSE BEGIN
248 Result.imgdepth:=16;
249 Result.storetype:=1;
250 END;
251
252 SetLength(Result.imgdata,Result.imgx*Result.imgy*Result.imgdepth DIV 8);
253 IF _32bit THEN BEGIN
254 FOR y:=0 TO Result.imgy-1 DO BEGIN
255 FOR x:=0 TO Result.imgx-1 DO BEGIN
256 Result.imgdata[((Result.imgx*y+x)*4)+0]:=bmpdata[54+(Result.imgx*y+x)*3+0];
257 Result.imgdata[((Result.imgx*y+x)*4)+1]:=bmpdata[54+(Result.imgx*y+x)*3+1];
258 Result.imgdata[((Result.imgx*y+x)*4)+2]:=bmpdata[54+(Result.imgx*y+x)*3+2];
259 Result.imgdata[((Result.imgx*y+x)*4)+3]:=0;
260 END;
261 END;
262 END ELSE BEGIN
263 FOR y:=0 TO Result.imgy-1 DO BEGIN
264 FOR x:=0 TO Result.imgx-1 DO BEGIN
265 r24:=bmpdata[54+(Result.imgx*y+x)*3+0];
266 g24:=bmpdata[54+(Result.imgx*y+x)*3+1];
267 b24:=bmpdata[54+(Result.imgx*y+x)*3+2];
268 r16:=(Ceil(r24*$001F/255)) AND $001F;
269 g16:=(Ceil(g24*$03E0/255)) AND $03E0;
270 b16:=(Ceil(b24*$7C00/255)) AND $7C00;
271 gesamt:=r16+g16+b16;
272 Result.imgdata[((Result.imgx*y+x)*2)+0]:=gesamt AND $00FF;
273 Result.imgdata[((Result.imgx*y+x)*2)+1]:=(gesamt AND $FF00) DIV 256;
274 END;
275 END;
276 END;
277
278 Result.imgdata:=RevertImage(Result.imgx,Result.imgy,Result.imgdepth,Result.imgdata);
279 END;
280
281FUNCTION LoadTXMBconnected(fileid:LongWord):TImgPackage;
282 VAR
283 i,x,y,x2,y2,pixelid,imgid:LongWord;
284 rows,cols:Word;
285 linkcount:LongWord;
286 link:LongWord;
287 single_image:TImgPackage;
288 images_decoded:Array OF TImgPackage;
289 x_start,y_start:LongWord;
290 BEGIN
291 OniDataConnection.LoadDatFilePart(fileid,$10,SizeOf(Result.imgx),@Result.imgx);
292 OniDataConnection.LoadDatFilePart(fileid,$12,SizeOf(Result.imgy),@Result.imgy);
293 OniDataConnection.LoadDatFilePart(fileid,$18,SizeOf(cols),@cols);
294 OniDataConnection.LoadDatFilePart(fileid,$1A,SizeOf(rows),@rows);
295 OniDataConnection.LoadDatFilePart(fileid,$1C,SizeOf(linkcount),@linkcount);
296 SetLength(images_decoded,linkcount);
297 FOR i:=0 TO linkcount-1 DO BEGIN
298 OniDataConnection.LoadDatFilePart(fileid,$20+i*4,SizeOf(link),@link);
299 link:=link DIV 256;
300 single_image:=LoadImgData(link);
301 images_decoded[i]:=BmpToImgdata(ImgdataToBmp(single_image.imgx,single_image.imgy,single_image.imgdepth,single_image.storetype,single_image.imgdata),False);
302 END;
303 SetLength(Result.imgdata,Result.imgx*Result.imgy*2);
304 FOR y:=0 TO rows-1 DO BEGIN
305 FOR x:=0 TO cols-1 DO BEGIN
306 imgid:=y*cols+x;
307 x_start:=0;
308 y_start:=0;
309 FOR i:=0 TO x DO IF i<x THEN x_start:=x_start+images_decoded[i].imgx;
310 FOR i:=0 TO y DO IF i<y THEN y_start:=y_start+images_decoded[i].imgy;
311 FOR y2:=0 TO images_decoded[imgid].imgy-1 DO BEGIN
312 FOR x2:=0 TO images_decoded[imgid].imgx-1 DO BEGIN
313 IF ( (x_start+x2)<Result.imgx ) AND ( (y_start+y2)<Result.imgy ) THEN BEGIN
314 pixelid:=y_start*Result.imgx+x_start+y2*Result.imgx+x2;
315 Result.imgdata[pixelid*2+0]:=images_decoded[imgid].imgdata[(y2*images_decoded[imgid].imgx+x2)*2+0];
316 Result.imgdata[pixelid*2+1]:=images_decoded[imgid].imgdata[(y2*images_decoded[imgid].imgx+x2)*2+1];
317 END;
318 END;
319 END;
320 END;
321 END;
322 Result.imgdepth:=16;
323 Result.storetype:=1;
324 END;
325
326FUNCTION LoadImgData(fileid:LongWord):TImgPackage;
327 VAR
328 img_addr:LongWord;
329 BEGIN
330 OniDataConnection.LoadDatFilePart(fileid,$8C,SizeOf(Result.imgx),@Result.imgx);
331 OniDataConnection.LoadDatFilePart(fileid,$8E,SizeOf(Result.imgy),@Result.imgy);
332 OniDataConnection.LoadDatFilePart(fileid,$90,SizeOf(Result.storetype),@Result.storetype);
333 IF NOT OniDataConnection.OSisMac THEN
334 OniDataConnection.LoadDatFilePart(fileid,$9C,SizeOf(img_addr),@img_addr)
335 ELSE
336 OniDataConnection.LoadDatFilePart(fileid,$A0,SizeOf(img_addr),@img_addr);
337
338 CASE Result.storetype OF
339 0,1,2: BEGIN
340 Result.datasize:=Result.imgx*Result.imgy*2;
341 Result.imgdepth:=16;
342 END;
343 8: BEGIN
344 Result.datasize:=Result.imgx*Result.imgy*4;
345 Result.imgdepth:=32;
346 END;
347 9: BEGIN
348 Result.datasize:=Result.imgx*Result.imgy DIV 2;
349 Result.imgdepth:=16;
350 END;
351 ELSE
352 Exit;
353 END;
354 SetLength(Result.imgdata,Result.datasize);
355
356 IF NOT OniDataConnection.OSisMac THEN
357 OniDataConnection.LoadRawFile(fileid,$9C,@Result.imgdata[0])
358 ELSE
359 OniDataConnection.LoadRawFile(fileid,$A0,@Result.imgdata[0]);
360 END;
361
362FUNCTION GetImageDataSize(imgx,imgy,imgdepth:Word; fading:Boolean):LongWord;
363 VAR
364 size:LongWord;
365 x,y:Word;
366 BEGIN
367 x:=imgx;
368 y:=imgy;
369 size:=x*y*imgdepth DIV 8;
370 IF fading THEN BEGIN
371 REPEAT
372 x:=x DIV 2;
373 y:=y DIV 2;
374 size:=size+x*y*imgdepth DIV 8;
375 UNTIL (x=1) OR (y=1);
376 END;
377 Result:=size;
378 END;
379
380FUNCTION CreateFadedImage(image:TImgPackage; VAR faded:Tdata):Boolean;
381 VAR
382 i:LongWord;
383 x,y:Word;
384 imgdata:Tdata;
385 fadelvldata:Tdata;
386 BEGIN
387 Result:=False;
388 x:=image.imgx;
389 y:=image.imgy;
390 SetLength(imgdata,x*y*image.imgdepth DIV 8);
391 SetLength(fadelvldata,x*y*image.imgdepth DIV 8);
392 FOR i:=0 TO Length(imgdata)-1 DO BEGIN
393 imgdata[i]:=image.imgdata[i];
394 fadelvldata[i]:=image.imgdata[i];
395 END;
396 REPEAT
397 fadelvldata:=ResizeImage(x,y,image.imgdepth,fadelvldata);
398 x:=x DIV 2;
399 y:=y DIV 2;
400 SetLength(imgdata,Length(imgdata)+x*y*image.imgdepth DIV 8);
401 FOR i:=0 TO Length(fadelvldata)-1 DO imgdata[Length(imgdata)-x*y*image.imgdepth DIV 8+i]:=fadelvldata[i];
402 UNTIL (x=1) OR (y=1) OR ((x MOD 2)=1) OR ((y MOD 2)=1);
403 IF (x>1) AND (y>1) THEN Exit;
404 Result:=True;
405 SetLength(faded, Length(imgdata));
406 FOR i:=0 TO Length(imgdata)-1 DO faded[i]:=imgdata[i];
407 END;
408
409END.
Note: See TracBrowser for help on using the repository browser.