source: oup/current/Unit6_imgfuncs.pas@ 33

Last change on this file since 33 was 10, checked in by alloc, 18 years ago
  • Property svn:executable set to *
File size: 22.7 KB
Line 
1unit Unit6_imgfuncs;
2interface
3uses Math, Dialogs, Types, SysUtils, Classes, Unit3_data, Unit15_Classes;
4
5type
6 TImgDataType=Set of (DT_OniReverted,DT_Oni,DT_Decoded32);
7
8type
9 TOniImage = class
10 private
11 FLoaded:Boolean;
12 FDataType:TImgDataType;
13 FData:Tdata;
14 FWidth,FHeight:Word;
15 FDepth:Byte;
16 FStoreType:Byte;
17
18 function ResizeImage(oldx,oldy:LongWord; img:Tdata):Tdata;
19 procedure RevertImage;
20 procedure DecodeImage;
21 procedure DecompressImage;
22 protected
23 public
24 property Loaded:Boolean read FLoaded write FLoaded;
25 property DataType:TImgDataType read FDataType write FDataType;
26 property Width:Word read FWidth write FWidth;
27 property Height:Word read FHeight write FHeight;
28 property Depth:Byte read FDepth write FDepth;
29 property StoreType:Byte read FStoreType write FStoreType;
30 property Data:Tdata read FData write FData;
31
32 constructor Create;
33 function LoadFromPSpc(fileid:LongWord):Boolean;
34 function LoadFromTXMP(fileid:LongWord):Boolean;
35 function LoadFromTXMB(fileid:LongWord):Boolean;
36 function GetImageDataSize(fading:Boolean):LongWord;
37
38 function GetAsData:Tdata;
39 function GetAs32bit:Tdata;
40 function GetAsBMP:Tdata;
41 function LoadFromBMP(filename:String):Boolean;
42 function WriteToBMP(filename:String):Boolean;
43 function GetMipMappedImage(var faded:Tdata):Boolean;
44 published
45 end;
46
47
48implementation
49uses Unit2_functions;
50
51
52
53constructor TOniImage.Create;
54 begin
55 Self.FLoaded:=False;
56 Self.FDataType:=[];
57 SetLength(Self.FData,0);
58 Self.FWidth:=0;
59 Self.FHeight:=0;
60 Self.FDepth:=0;
61 Self.FStoreType:=0;
62 end;
63
64
65
66function TOniImage.ResizeImage(oldx,oldy:LongWord; img:Tdata):Tdata;
67 var
68 i,j:LongWord;
69 col,row,row_orig:LongWord;
70 begin
71 SetLength(Result,(oldx div 2)*(oldy div 2)*(Self.FDepth div 8));
72 row_orig:=0;
73 row:=0;
74 col:=0;
75 for i:=0 to (oldx*oldy)-1 do begin
76 if ((i mod oldx)=0) and (i>0) then begin
77 Inc(row_orig);
78 if (row_orig mod 2)=0 then begin
79 Inc(row);
80 col:=0;
81 end;
82 end;
83 if (row_orig mod 2)=0 then begin
84 if (i mod 2)=0 then begin
85 for j:=0 to (Self.FDepth div 8)-1 do
86 Result[((row*(oldx div 2))+col)*(Self.FDepth div 8)+j]:=img[(i*(Self.FDepth div 8))+j];
87 Inc(col);
88 end;
89 end;
90 end;
91 end;
92
93
94
95procedure TOniImage.RevertImage;
96 var
97 x,y,i:LongWord;
98 tempd:Tdata;
99 begin
100 SetLength(tempd, Self.FWidth * Self.FHeight *(Self.FDepth div 8));
101 for y:=0 to Self.FHeight-1 do
102 for x:=0 to Self.FWidth-1 do
103 for i:=0 to (Self.FDepth div 8)-1 do
104 tempd[((Self.FWidth*(Self.FHeight-1-y)+x)*(Self.FDepth div 8))+i]:=
105 Self.FData[(Self.FWidth*y+x)*(Self.FDepth div 8)+i];
106 for x:=0 to High(tempd) do
107 Self.FData[x]:=tempd[x];
108 if DT_OniReverted in Self.FDataType then
109 Self.FDataType:=Self.FDataType-[DT_OniReverted]
110 else
111 Self.FDataType:=Self.FDataType+[DT_OniReverted];
112 end;
113
114
115
116procedure TOniImage.DecodeImage;
117 var
118 x,y:LongWord;
119 tempd:Tdata;
120 begin
121 if not (DT_Decoded32 in Self.FDataType) then begin
122 SetLength(tempd, Self.FWidth * Self.FHeight * 4);
123 case Self.FStoreType of
124 0: begin
125 for y:=0 to Self.FHeight-1 do begin
126 for x:=0 to Self.FWidth-1 do begin
127 tempd[((Self.FWidth*y+x)*4)+0]:=Floor( ( (Self.FData[(Self.FWidth*y+x)*2]+Self.FData[(Self.FWidth*y+x)*2+1]*256) AND $000F ) / $000F * 255);
128 tempd[((Self.FWidth*y+x)*4)+1]:=Floor( ( (Self.FData[(Self.FWidth*y+x)*2]+Self.FData[(Self.FWidth*y+x)*2+1]*256) AND $00F0 ) / $00F0 * 255);
129 tempd[((Self.FWidth*y+x)*4)+2]:=Floor( ( (Self.FData[(Self.FWidth*y+x)*2]+Self.FData[(Self.FWidth*y+x)*2+1]*256) AND $0F00 ) / $0F00 * 255);
130 tempd[((Self.FWidth*y+x)*4)+3]:=0;
131 end;
132 end;
133 end;
134 1,2: begin
135 for y:=0 to Self.FHeight-1 do begin
136 for x:=0 to Self.FWidth-1 do begin
137 tempd[((Self.FWidth*y+x)*4)+0]:=Floor( ( (Self.FData[(Self.FWidth*y+x)*2]+Self.FData[(Self.FWidth*y+x)*2+1]*256) AND $001F ) / $001F * 255);
138 tempd[((Self.FWidth*y+x)*4)+1]:=Floor( ( (Self.FData[(Self.FWidth*y+x)*2]+Self.FData[(Self.FWidth*y+x)*2+1]*256) AND $03E0 ) / $03E0 * 255);
139 tempd[((Self.FWidth*y+x)*4)+2]:=Floor( ( (Self.FData[(Self.FWidth*y+x)*2]+Self.FData[(Self.FWidth*y+x)*2+1]*256) AND $7C00 ) / $7C00 * 255);
140 tempd[((Self.FWidth*y+x)*4)+3]:=0;
141 end;
142 end;
143 end;
144 9: begin
145 DecompressImage;
146 end;
147 end;
148 Self.FDepth:=32;
149 if (Self.FStoreType<>9) AND (Self.FStoreType<>8) then begin
150 SetLength(Self.FData, Length(tempd));
151 for x:=0 to High(tempd) do
152 Self.FData[x]:=tempd[x];
153 end;
154 Self.FStoreType:=8;
155 if DT_Oni in Self.FDataType then
156 Self.FDataType:=Self.FDataType-[DT_Oni];
157 Self.FDataType:=Self.FDataType+[DT_Decoded32];
158 end;
159 if DT_OniReverted in Self.FDataType then
160 Self.RevertImage;
161 end;
162
163
164
165procedure TOniImage.DecompressImage;
166 type
167 Tcolor=record
168 RGBb:Byte;
169 RGBg:Byte;
170 RGBr:Byte;
171 RGBa:Byte;
172 end;
173 var
174 i,j,x,y:LongWord;
175 color:Array[1..4] of Tcolor;
176 pixel:Array[1..16] of Byte;
177 tempd:Tdata;
178 begin
179 x:=0;
180 y:=0;
181 SetLength(tempd, Self.FWidth * Self.FHeight * 4);
182 for i:=0 to ((Self.FWidth * Self.FHeight) div 16)-1 do begin
183 Color[1].RGBb:=Floor(((Self.FData[(i*8)+0]+Self.FData[(i*8)+1]*256) and $001F) / $001F * 255);
184 Color[1].RGBg:=Floor(((Self.FData[(i*8)+0]+Self.FData[(i*8)+1]*256) and $07E0) / $07E0 * 255);
185 Color[1].RGBr:=Floor(((Self.FData[(i*8)+0]+Self.FData[(i*8)+1]*256) and $F800) / $F800 * 255);
186 Color[1].RGBa:=255;
187 Color[2].RGBb:=Floor(((Self.FData[(i*8)+2]+Self.FData[(i*8)+3]*256) and $001F) / $001F * 255);
188 Color[2].RGBg:=Floor(((Self.FData[(i*8)+2]+Self.FData[(i*8)+3]*256) and $07E0) / $07E0 * 255);
189 Color[2].RGBr:=Floor(((Self.FData[(i*8)+2]+Self.FData[(i*8)+3]*256) and $F800) / $F800 * 255);
190 Color[2].RGBa:=255;
191 Color[3].RGBb:=Floor( Color[1].RGBb/3*2 + Color[2].RGBb/3 );
192 Color[3].RGBg:=Floor( Color[1].RGBg/3*2 + Color[2].RGBg/3 );
193 Color[3].RGBr:=Floor( Color[1].RGBr/3*2 + Color[2].RGBr/3 );
194 Color[3].RGBa:=255;
195 Color[4].RGBb:=Floor( Color[1].RGBb/3 + Color[2].RGBb/3*2 );
196 Color[4].RGBg:=Floor( Color[1].RGBg/3 + Color[2].RGBg/3*2 );
197 Color[4].RGBr:=Floor( Color[1].RGBr/3 + Color[2].RGBr/3*2 );
198 Color[4].RGBa:=255;
199 Pixel[1]:=Floor( (Self.FData[(i*8)+4] and $C0) / $40 + 1 );
200 Pixel[2]:=Floor( (Self.FData[(i*8)+4] and $30) / $10 + 1 );
201 Pixel[3]:=Floor( (Self.FData[(i*8)+4] and $0C) / $04 + 1 );
202 Pixel[4]:=Floor( (Self.FData[(i*8)+4] and $03) + 1 );
203 Pixel[5]:=Floor( (Self.FData[(i*8)+5] and $C0) / $40 + 1 );
204 Pixel[6]:=Floor( (Self.FData[(i*8)+5] and $30) / $10 + 1 );
205 Pixel[7]:=Floor( (Self.FData[(i*8)+5] and $0C) / $04 + 1 );
206 Pixel[8]:=Floor( (Self.FData[(i*8)+5] and $03) + 1 );
207 Pixel[9]:=Floor( (Self.FData[(i*8)+6] and $C0) / $40 + 1 );
208 Pixel[10]:=Floor( (Self.FData[(i*8)+6] and $30) / $10 + 1 );
209 Pixel[11]:=Floor( (Self.FData[(i*8)+6] and $0C) / $04 + 1 );
210 Pixel[12]:=Floor( (Self.FData[(i*8)+6] and $03) + 1 );
211 Pixel[13]:=Floor( (Self.FData[(i*8)+7] and $C0) / $40 + 1 );
212 Pixel[14]:=Floor( (Self.FData[(i*8)+7] and $30) / $10 + 1 );
213 Pixel[15]:=Floor( (Self.FData[(i*8)+7] and $0C) / $04 + 1 );
214 Pixel[16]:=Floor( (Self.FData[(i*8)+7] and $03) + 1 );
215 for j:=0 to 3 do begin
216 tempd[((y+3)*Self.FWidth+x+j)*4+0]:=Color[Pixel[16-j]].RGBb;
217 tempd[((y+3)*Self.FWidth+x+j)*4+1]:=Color[Pixel[16-j]].RGBg;
218 tempd[((y+3)*Self.FWidth+x+j)*4+2]:=Color[Pixel[16-j]].RGBr;
219 tempd[((y+3)*Self.FWidth+x+j)*4+3]:=0;
220 end;
221 for j:=0 to 3 do begin
222 tempd[((y+2)*Self.FWidth+x+j)*4+0]:=Color[Pixel[12-j]].RGBb;
223 tempd[((y+2)*Self.FWidth+x+j)*4+1]:=Color[Pixel[12-j]].RGBg;
224 tempd[((y+2)*Self.FWidth+x+j)*4+2]:=Color[Pixel[12-j]].RGBr;
225 tempd[((y+2)*Self.FWidth+x+j)*4+3]:=0;
226 end;
227 for j:=0 to 3 do begin
228 tempd[((y+1)*Self.FWidth+x+j)*4+0]:=Color[Pixel[8-j]].RGBb;
229 tempd[((y+1)*Self.FWidth+x+j)*4+1]:=Color[Pixel[8-j]].RGBg;
230 tempd[((y+1)*Self.FWidth+x+j)*4+2]:=Color[Pixel[8-j]].RGBr;
231 tempd[((y+1)*Self.FWidth+x+j)*4+3]:=0;
232 end;
233 for j:=0 to 3 do begin
234 tempd[((y+0)*Self.FWidth+x+j)*4+0]:=Color[Pixel[4-j]].RGBb;
235 tempd[((y+0)*Self.FWidth+x+j)*4+1]:=Color[Pixel[4-j]].RGBg;
236 tempd[((y+0)*Self.FWidth+x+j)*4+2]:=Color[Pixel[4-j]].RGBr;
237 tempd[((y+0)*Self.FWidth+x+j)*4+3]:=0;
238 end;
239 x:=x+4;
240 if x=Self.FWidth THEN begin
241 y:=y+4;
242 x:=0;
243 end;
244 end;
245 SetLength(Self.FData, Length(tempd));
246 for i:=0 to High(tempd) do
247 Self.FData[i]:=tempd[i];
248 Self.FStoreType:=8;
249 Self.FDepth:=32;
250 Self.FDataType:=Self.FDataType-[DT_Oni]+[DT_Decoded32];
251 end;
252
253
254
255
256
257function TOniImage.LoadFromPSpc(fileid:LongWord):Boolean;
258 type
259 TPoint=Packed Record
260 X,Y:Word;
261 end;
262 TPSpc=Packed Record
263 p1:Array[0..8] of TPoint;
264 p2:Array[0..8] of TPoint;
265 TXMP:LongWord;
266 end;
267 TPart=Packed Record
268 x_txmp,y_txmp:Word;
269 x_pspc,y_pspc:Word;
270 w,h:Word;
271 imgdata:Tdata;
272 used:Boolean;
273 end;
274 const
275 PartMatch:Array[0..8] of Byte=(0,3,6,1,4,7,2,5,8);
276 var
277 x,y,pixel:Word;
278 i:Integer;
279
280 PSpc:TPSpc;
281 txmpimg:TOniImage;
282 txmpdata:Tdata;
283
284 parts:Array[0..8] of TPart;
285 part:Byte;
286 cols:Array[0..2] of Word;
287 rows:Array[0..2] of Word;
288 col,row:Byte;
289 begin
290 OniDataConnection.LoadDatFilePart ( fileid , $08 , SizeOf(PSpc) , @PSpc );
291 PSpc.TXMP := PSpc.TXMP div 256;
292 if PSpc.TXMP = 0 then begin
293 Result := False;
294 Exit;
295 end;
296 txmpimg := TOniImage.Create;
297 txmpimg.LoadFromTXMP ( PSpc.TXMP );
298 txmpimg.DecodeImage;
299 txmpimg.WriteToBMP('D:\file.bmp');
300 txmpdata:=txmpimg.GetAs32bit;
301{ ShowMessage(IntToStr(txmpimg.Width)+'x'+IntToStr(txmpimg.Height));
302 for i:=0 to High(txmpdata) do
303 txmpimg.Data[i]:=txmpdata[i];
304 txmpimg.WriteToBMP('D:\file2.bmp');
305}
306 with PSpc do begin
307 for i := 0 to 2 do begin
308 cols[i] := 0;
309 rows[i] := 0;
310 end;
311 for i := 0 to 8 do begin
312 part := PartMatch[i];
313 col := i div 3;
314 row := i mod 3;
315 if (p2[i].X>0) or (p2[i].Y>0) then begin
316 parts[part].x_txmp := p1[i].X - 1;
317 parts[part].y_txmp := p1[i].Y - 1;
318 parts[part].x_pspc := 0;
319 if col>0 then
320 for x := 0 to col-1 do
321 Inc( parts[part].x_pspc , cols[x] );
322 parts[part].y_pspc := 0;
323 if row>0 then
324 for y := 0 to row-1 do
325 Inc ( parts[part].y_pspc , rows[y] );
326 parts[part].w := p2[i].X - p1[i].X + 1;
327 parts[part].h := p2[i].Y - p1[i].Y + 1;
328 parts[part].used := True;
329 cols[col] := parts[part].w;
330 rows[row] := parts[part].h;
331 SetLength(parts[part].imgdata, parts[part].w * parts[part].h * 4);
332 for y := 0 to parts[part].h-1 do begin
333 for x := 0 to parts[part].w-1 do begin
334 for pixel := 0 to 3 do begin
335 parts[part].imgdata[ ( y*parts[part].w + x ) * 4 + pixel ] :=
336 txmpdata[ ( ( parts[part].y_txmp + y ) * txmpimg.Width + parts[part].x_txmp + x ) * 4 + pixel ];
337 end;
338 end;
339 end;
340 end else begin
341 parts[part].used := False;
342 end;
343 end;
344
345 end;
346
347 txmpimg.Free;
348 txmpimg:=TOniImage.Create;
349 for i:=0 to 8 do begin
350 if parts[i].used then begin
351 SetLength( txmpimg.FData, Length(parts[i].imgdata) );
352 for pixel:=0 to High(parts[i].imgdata) do
353 txmpimg.Data[pixel]:=parts[i].imgdata[pixel];
354 txmpimg.Width:=parts[i].w;
355 txmpimg.Height:=parts[i].h;
356 txmpimg.StoreType:=8;
357 txmpimg.DataType:=[DT_Decoded32];
358 txmpimg.Depth:=32;
359 txmpimg.WriteToBMP('D:\'+IntToStr(i)+'.bmp');
360 end;
361 end;
362 txmpimg.Free;
363
364 Self.FWidth := 0;
365 Self.FHeight := 0;
366 for i := 0 to 2 do begin
367 Inc( Self.FWidth , cols[i] );
368 Inc( Self.FHeight , rows[i] );
369 end;
370 SetLength(Self.FData, Self.FWidth * Self.FHeight * 4);
371
372//Combine data parts
373
374 Self.FDepth:=32;
375 Self.FStoreType:=8;
376 Self.FDataType:=[DT_Decoded32];
377// Self.RevertImage;
378 end;
379
380
381function TOniImage.LoadFromTXMP(fileid:LongWord):Boolean;
382 var
383 img_addr:LongWord;
384 begin
385 Result:=True;
386 OniDataConnection.LoadDatFilePart(fileid,$8C,SizeOf(Self.FWidth),@Self.FWidth);
387 OniDataConnection.LoadDatFilePart(fileid,$8E,SizeOf(Self.FHeight),@Self.FHeight);
388 OniDataConnection.LoadDatFilePart(fileid,$90,SizeOf(Self.FStoreType),@Self.FStoreType);
389 if not OniDataConnection.OSisMac then
390 OniDataConnection.LoadDatFilePart(fileid,$9C,SizeOf(img_addr),@img_addr)
391 else
392 OniDataConnection.LoadDatFilePart(fileid,$A0,SizeOf(img_addr),@img_addr);
393
394 case Self.FStoreType of
395 0,1,2: begin
396 SetLength(Self.FData, Self.FWidth * Self.FHeight * 2);
397 Self.FDepth:=16;
398 end;
399 8: begin
400 SetLength(Self.FData, Self.FWidth * Self.FHeight * 4);
401 Self.FDepth:=32;
402 end;
403 9: begin
404 SetLength(Self.FData, Self.FWidth * Self.FHeight div 2);
405 Self.FDepth:=16;
406 end;
407 else
408 Result:=False;
409 Exit;
410 end;
411
412 if not OniDataConnection.OSisMac then
413 OniDataConnection.LoadRawFile(fileid,$9C,@Self.FData[0])
414 else
415 OniDataConnection.LoadRawFile(fileid,$A0,@Self.FData[0]);
416
417 Self.FDataType:=[DT_OniReverted,DT_Oni];
418 end;
419
420
421
422function TOniImage.LoadFromTXMB(fileid:LongWord):Boolean;
423 var
424 i,x,y,x2,y2,pixelid,imgid:LongWord;
425 rows,cols:Word;
426 linkcount:LongWord;
427 link:LongWord;
428 images_decoded:Array of TOniImage;
429 x_start,y_start:LongWord;
430 begin
431 OniDataConnection.LoadDatFilePart(fileid,$10,SizeOf(Self.FWidth),@Self.FWidth);
432 OniDataConnection.LoadDatFilePart(fileid,$12,SizeOf(Self.FHeight),@Self.FHeight);
433 OniDataConnection.LoadDatFilePart(fileid,$18,SizeOf(cols),@cols);
434 OniDataConnection.LoadDatFilePart(fileid,$1A,SizeOf(rows),@rows);
435 OniDataConnection.LoadDatFilePart(fileid,$1C,SizeOf(linkcount),@linkcount);
436 SetLength(images_decoded,linkcount);
437 for i:=0 to linkcount-1 do begin
438 OniDataConnection.LoadDatFilePart(fileid,$20+i*4,SizeOf(link),@link);
439 link:=link div 256;
440 images_decoded[i]:=TOniImage.Create;
441 images_decoded[i].LoadFromTXMP(link);
442 images_decoded[i].DecodeImage;
443 images_decoded[i].RevertImage;
444 end;
445 SetLength(Self.FData, Self.FWidth * Self.FHeight * 4);
446 for y:=0 to rows-1 do begin
447 for x:=0 to cols-1 do begin
448 imgid:=y*cols+x;
449 x_start:=0;
450 y_start:=0;
451 for i:=0 to x do if i<x then x_start:=x_start+images_decoded[i].Width;
452 for i:=0 to y do if i<y then y_start:=y_start+images_decoded[i].Height;
453 for y2:=0 to images_decoded[imgid].Height-1 do begin
454 for x2:=0 to images_decoded[imgid].Width-1 do begin
455 if ( (x_start+x2)<Self.FWidth ) and ( (y_start+y2)<Self.FHeight ) then begin
456 pixelid:=y_start*Self.FWidth+x_start+y2*Self.FWidth+x2;
457 Self.FData[pixelid*4+0]:=images_decoded[imgid].Data[(y2*images_decoded[imgid].Width+x2)*4+0];
458 Self.FData[pixelid*4+1]:=images_decoded[imgid].Data[(y2*images_decoded[imgid].Width+x2)*4+1];
459 Self.FData[pixelid*4+2]:=images_decoded[imgid].Data[(y2*images_decoded[imgid].Width+x2)*4+2];
460 Self.FData[pixelid*4+3]:=images_decoded[imgid].Data[(y2*images_decoded[imgid].Width+x2)*4+3];
461 end;
462 end;
463 end;
464 end;
465 end;
466 for i:=0 to linkcount-1 do
467 images_decoded[i].Free;
468 Self.FDepth:=32;
469 Self.FStoreType:=8;
470 Self.FDataType:=[DT_Decoded32];
471 Self.RevertImage;
472 end;
473
474
475
476function TOniImage.GetImageDataSize(fading:Boolean):LongWord;
477 var
478 size:LongWord;
479 x,y:Word;
480 bpp:Byte;
481 begin
482 case Self.FStoreType of
483 9: bpp:=8;
484 0,1,2: bpp:=16;
485 8: bpp:=32;
486 else
487 Result:=0;
488 Exit;
489 end;
490
491 x:=Self.FWidth;
492 y:=Self.FHeight;
493 size:=x*y*bpp div 8;
494 if fading then begin
495 repeat
496 x:=x div 2;
497 y:=y div 2;
498 size:=size+x*y*bpp div 8;
499 until (x=1) or (y=1);
500 end;
501 Result:=size;
502 end;
503
504
505
506function TOniImage.GetAsData:Tdata;
507 var
508 i: Integer;
509 revert:Boolean;
510 begin
511// if not (DT_Decoded32 in Self.FDataType) then
512// Self.DecodeImage;
513 if not (DT_OniReverted in Self.FDataType) then begin
514 revert:=True;
515 Self.RevertImage;
516 end else revert:=False;
517 SetLength(Result, Length(Self.FData));
518 for i:=0 to High(Result) do
519 Result[i]:=Self.FData[i];
520 if revert then
521 Self.RevertImage;
522 end;
523
524
525
526function TOniImage.GetAs32bit:Tdata;
527 var
528 i:Integer;
529 begin
530 if not (DT_Decoded32 in Self.FDataType) then
531 Self.DecodeImage;
532 SetLength(Result,Length(Self.FData));
533 for i:=0 to High(Result) do
534 Result[i]:=Self.FData[i];
535 end;
536
537
538
539function TOniImage.GetAsBMP:Tdata;
540 const BMPheader:Array[0..53] of Byte=
541 ($42,$4D,0,0,0,0,0,0,0,0,54,0,0,0,
542 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);
543 var
544 i,x,y:LongWord;
545 begin
546 if not (DT_Decoded32 in Self.FDataType) then
547 Self.DecodeImage;
548
549 SetLength(Result, Self.FWidth * Self.FHeight * 3 + 54);
550 for y:=0 to Self.FHeight-1 do begin
551 for x:=0 to Self.FWidth-1 do begin
552 Result[((Self.FWidth*y+x)*3)+0+54]:=Self.FData[(Self.FWidth*y+x)*4+0];
553 Result[((Self.FWidth*y+x)*3)+1+54]:=Self.FData[(Self.FWidth*y+x)*4+1];
554 Result[((Self.FWidth*y+x)*3)+2+54]:=Self.FData[(Self.FWidth*y+x)*4+2];
555 end;
556 end;
557
558 for i:=0 to High(BMPheader) do
559 Result[i]:=BMPheader[i];
560 Result[2]:=((Self.FWidth*Self.FHeight*3+54) and $000000FF) div $1;
561 Result[3]:=((Self.FWidth*Self.FHeight*3+54) and $0000FF00) div $100;
562 Result[4]:=((Self.FWidth*Self.FHeight*3+54) and $00FF0000) div $10000;
563 Result[5]:=((Self.FWidth*Self.FHeight*3+54) and $FF000000) div $1000000;
564 Result[18]:=(Self.FWidth and $000000FF) div $1;
565 Result[19]:=(Self.FWidth and $0000FF00) div $100;
566 Result[20]:=(Self.FWidth and $00FF0000) div $10000;
567 Result[21]:=(Self.FWidth and $FF000000) div $1000000;
568 Result[22]:=(Self.FHeight and $000000FF) div $1;
569 Result[23]:=(Self.FHeight and $0000FF00) div $100;
570 Result[24]:=(Self.FHeight and $00FF0000) div $10000;
571 Result[25]:=(Self.FHeight and $FF000000) div $1000000;
572 Result[34]:=((Self.FWidth*Self.FHeight*3) and $000000FF) div $1;
573 Result[35]:=((Self.FWidth*Self.FHeight*3) and $0000FF00) div $100;
574 Result[36]:=((Self.FWidth*Self.FHeight*3) and $00FF0000) div $10000;
575 Result[37]:=((Self.FWidth*Self.FHeight*3) and $FF000000) div $1000000;
576 end;
577
578
579
580function TOniImage.LoadFromBMP(filename:String):Boolean;
581 var
582 filestream:TFileStream;
583 tempd:Tdata;
584
585 x,y:LongWord;
586 begin
587 filestream:=TFileStream.Create(filename, fmOpenRead);
588 SetLength(tempd,filestream.Size);
589 filestream.Read(tempd[0],filestream.Size);
590 filestream.Free;
591
592 if not((tempd[00]=$42) and (tempd[01]=$4D)) then begin
593 Result:=False;
594 ShowMessage('Not a standard 24bit bitmap');
595 Exit;
596 end;
597 if not(tempd[10]=54) then begin
598 Result:=False;
599 ShowMessage('Imagedata has to start at 0x54');
600 Exit;
601 end;
602 if not(tempd[14]=40) then begin
603 Result:=False;
604 ShowMessage('Second bitmap header has to have 40 bytes');
605 Exit;
606 end;
607 if not(tempd[28]=24) then begin
608 Result:=False;
609 ShowMessage('Bitmap has to have 24bits');
610 Exit;
611 end;
612 if not(tempd[30]=0) then begin
613 Result:=False;
614 ShowMessage('Bitmap has to be uncompressed');
615 Exit;
616 end;
617
618 Self.FWidth :=tempd[18]+tempd[19]*256+tempd[20]*256*256+tempd[21]*256*256*256;
619 Self.FHeight:=tempd[22]+tempd[23]*256+tempd[24]*256*256+tempd[25]*256*256*256;
620 Self.FDepth:=32;
621 Self.FStoreType:=8;
622
623 SetLength(Self.FData, Self.FWidth * Self.FHeight * Self.FDepth div 8);
624 for y:=0 to Self.FHeight-1 do begin
625 for x:=0 to Self.FWidth-1 do begin
626 Self.FData[((Self.FWidth*y+x)*4)+0]:=tempd[54+(Self.FWidth*y+x)*3+0];
627 Self.FData[((Self.FWidth*y+x)*4)+1]:=tempd[54+(Self.FWidth*y+x)*3+1];
628 Self.FData[((Self.FWidth*y+x)*4)+2]:=tempd[54+(Self.FWidth*y+x)*3+2];
629 Self.FData[((Self.FWidth*y+x)*4)+3]:=0;
630 end;
631 end;
632
633 Self.FDataType:=[DT_Decoded32];
634 end;
635
636
637
638function TOniImage.WriteToBMP(filename:String):Boolean;
639 var
640 filestream:TFileStream;
641 tempd:Tdata;
642 begin
643 tempd:=Self.GetAsBMP;
644 filestream:=TFileStream.Create(filename,fmCreate);
645 filestream.Write(tempd[0],Length(tempd));
646 filestream.Free;
647 end;
648
649
650
651function TOniImage.GetMipMappedImage(var faded:Tdata):Boolean;
652 var
653 i:LongWord;
654 x,y:Word;
655 fadelvldata:Tdata;
656 revert:Boolean;
657 begin
658 Result:=False;
659
660// if not (DT_Decoded32 in Self.FDataType) then
661// Self.DecodeImage;
662 if Self.FStoreType=9 then
663 Self.DecompressImage;
664 if not (DT_OniReverted in Self.FDataType) then begin
665 revert:=True;
666 Self.RevertImage;
667 end else revert:=False;
668
669 x:=Self.FWidth;
670 y:=Self.FHeight;
671 SetLength(faded,x*y*Self.FDepth div 8);
672 SetLength(fadelvldata,x*y*Self.FDepth div 8);
673 for i:=0 to Length(faded)-1 do begin
674 faded[i]:=Self.FData[i];
675 fadelvldata[i]:=Self.FData[i];
676 end;
677 repeat
678 fadelvldata:=Self.ResizeImage(x,y,fadelvldata);
679 x:=x div 2;
680 y:=y div 2;
681 SetLength(faded,Length(faded)+x*y*Self.FDepth div 8);
682 for i:=0 to Length(fadelvldata)-1 do
683 faded[Length(faded)-x*y*Self.FDepth div 8+i]:=fadelvldata[i];
684 until (x=1) or (y=1) or ((x mod 2)=1) or ((y mod 2)=1);
685 if (x>1) and (y>1) then Exit;
686 Result:=True;
687
688 if revert then
689 Self.RevertImage;
690 end;
691
692
693end.
Note: See TracBrowser for help on using the repository browser.