source: oup/current/Unit6_imgfuncs.pas @ 10

Last change on this file since 10 was 10, checked in by alloc, 17 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.