source: oup/releases/0.17a/Unit6_imgfuncs.pas @ 21

Last change on this file since 21 was 21, checked in by alloc, 17 years ago
File size: 14.8 KB
Line 
1UNIT Unit6_imgfuncs;
2INTERFACE
3USES Math, Dialogs, SysUtils, Unit3_data;
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):Tdata;
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*2+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    LoadDatFilePart(fileid,$10,SizeOf(Result.imgx),@Result.imgx);
292    LoadDatFilePart(fileid,$12,SizeOf(Result.imgy),@Result.imgy);
293    LoadDatFilePart(fileid,$18,SizeOf(cols),@cols);
294    LoadDatFilePart(fileid,$1A,SizeOf(rows),@rows);
295    LoadDatFilePart(fileid,$1C,SizeOf(linkcount),@linkcount);
296    SetLength(images_decoded,linkcount);
297    FOR i:=0 TO linkcount-1 DO BEGIN
298      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  BEGIN
328    LoadDatFilePart(fileid,$9C,SizeOf(Result.raw_addr),@Result.raw_addr);
329    LoadDatFilePart(fileid,$8C,SizeOf(Result.imgx),@Result.imgx);
330    LoadDatFilePart(fileid,$8E,SizeOf(Result.imgy),@Result.imgy);
331    LoadDatFilePart(fileid,$90,SizeOf(Result.storetype),@Result.storetype);
332
333    CASE Result.storetype OF
334      0,1,2: BEGIN
335          Result.datasize:=Result.imgx*Result.imgy*2;
336          Result.imgdepth:=16;
337        END;
338      8: BEGIN
339          Result.datasize:=Result.imgx*Result.imgy*4;
340          Result.imgdepth:=32;
341        END;
342      9: BEGIN
343          Result.datasize:=Result.imgx*Result.imgy DIV 2;
344          Result.imgdepth:=16;
345        END;
346    ELSE
347      Exit;
348    END;
349    SetLength(Result.imgdata,Result.datasize);
350
351    LoadRawFilePart(Result.raw_addr,Result.datasize,@Result.imgdata[0]);
352  END;
353
354FUNCTION GetImageDataSize(imgx,imgy,imgdepth:Word; fading:Boolean):LongWord;
355  VAR
356    size:LongWord;
357    x,y:Word;
358  BEGIN
359    x:=imgx;
360    y:=imgy;
361    size:=x*y*imgdepth DIV 8;
362    IF fading THEN BEGIN
363      REPEAT
364        x:=x DIV 2;
365        y:=y DIV 2;
366        size:=size+x*y*imgdepth DIV 8;
367      UNTIL (x=1) OR (y=1);
368    END;
369    Result:=size;
370  END;
371
372FUNCTION CreateFadedImage(image:TImgPackage):Tdata;
373  VAR
374    i:LongWord;
375    x,y:Word;
376    imgdata:Tdata;
377    fadelvldata:Tdata;
378  BEGIN
379    x:=image.imgx;
380    y:=image.imgy;
381    SetLength(imgdata,x*y*image.imgdepth DIV 8);
382    SetLength(fadelvldata,x*y*image.imgdepth DIV 8);
383    FOR i:=0 TO Length(imgdata)-1 DO BEGIN
384      imgdata[i]:=image.imgdata[i];
385      fadelvldata[i]:=image.imgdata[i];
386    END;
387    REPEAT
388      fadelvldata:=ResizeImage(x,y,image.imgdepth DIV 8,fadelvldata);
389      x:=x DIV 2;
390      y:=y DIV 2;
391      SetLength(imgdata,Length(imgdata)+x*y*image.imgdepth DIV 8);
392      FOR i:=0 TO Length(fadelvldata)-1 DO imgdata[Length(imgdata)-x*y*image.imgdepth DIV 8+i]:=fadelvldata[i];
393    UNTIL (x=1) OR (y=1);
394    SetLength(Result, Length(imgdata));
395    FOR i:=0 TO Length(imgdata)-1 DO Result[i]:=imgdata[i];
396  END;
397
398END.
Note: See TracBrowser for help on using the repository browser.