ViewVC Help
View File | Revision Log | View Changeset | Root Listing
root/Oni2/oup/current/Global/OniImgClass.pas
(Generate patch)

Comparing:
oup/rewrite/Global/OniImgClass.pas (file contents), Revision 105 by alloc, Wed Feb 21 00:29:27 2007 UTC vs.
oup/current/Global/OniImgClass.pas (file contents), Revision 181 by alloc, Sat May 19 17:54:34 2007 UTC

# Line 2 | Line 2 | unit OniImgClass;
2  
3   interface
4  
5 < uses Math, Dialogs, Types, SysUtils, Classes, Data, ConnectionManager, TypeDefs;
5 > uses Math, Dialogs, Types, SysUtils, Classes, Data, ConnectionManager, TypeDefs,
6 >  Imaging, ImagingTypes;
7  
8   type
9    TImgDataType = set of (DT_OniReverted, DT_Oni, DT_Decoded32);
10  
11 +
12   type
13    TOniImage = class
14    private
# Line 17 | Line 19 | type
19      FDepth:     Byte;
20      FStoreType: Byte;
21  
22 +    FImage:     TImageData;
23 +
24      function ResizeImage(oldx, oldy: Integer; img: TByteData): TByteData;
25      procedure RevertImage;
22    procedure DecodeImage;
26      procedure DecompressImage;
27    protected
28    public
29 +    property Image:     TImageData   Read FImage     Write FImage;
30      property Loaded:    Boolean      Read FLoaded    Write FLoaded;
31      property DataType:  TImgDataType Read FDataType  Write FDataType;
32      property Width:     Word         Read FWidth     Write FWidth;
# Line 36 | Line 40 | type
40      function LoadFromPSpc(ConnectionID, FileID: Integer): Boolean;
41      function LoadFromTXMP(ConnectionID, FileID: Integer): Boolean;
42      function LoadFromTXMB(ConnectionID, FileID: Integer): Boolean;
43 +    function GetImgSize(w,h, storetype: Integer): Integer;
44      function GetImageDataSize(fading: Boolean): Integer;
45  
46 +    procedure DecodeImageTo32bit;
47 +
48      procedure GetAsData(var Target: TStream); overload;
49      procedure GetAsData(var Target: TByteData); overload;
50      procedure GetAs32bit(var Target: TStream); overload;
# Line 55 | Line 62 | type
62   implementation
63  
64   //uses Functions;
65 <
59 <
65 > uses Img_DDSTypes;
66  
67  
68   constructor TOniImage.Create;
# Line 68 | Line 74 | begin
74    Self.FHeight    := 0;
75    Self.FDepth     := 0;
76    Self.FStoreType := 0;
77 +
78 +  InitImage(FImage);
79   end;
80  
81  
# Line 131 | Line 139 | end;
139  
140  
141  
142 < procedure TOniImage.DecodeImage;
142 > procedure TOniImage.DecodeImageTo32bit;
143   var
144    x, y:  Integer;
145    tempd: TByteData;
# Line 140 | Line 148 | begin
148    begin
149      SetLength(tempd, Self.FWidth * Self.FHeight * 4);
150      case Self.FStoreType of
151 <      0:
151 >      0: // 16bit, RGB444, A4?
152        begin
153          for y := 0 to Self.FHeight - 1 do
154          begin
# Line 159 | Line 167 | begin
167            end;
168          end;
169        end;
170 <      1, 2:
170 >      1, 2: // 16bit, RGB555, A1?
171        begin
172          for y := 0 to Self.FHeight - 1 do
173          begin
# Line 178 | Line 186 | begin
186            end;
187          end;
188        end;
189 <      9:
189 >      8: // 32bit, RGB888, A8?
190 >      begin end;
191 >      9: // Compressed, RGB565
192        begin
193          DecompressImage;
194        end;
# Line 309 | Line 319 | end;
319   function TOniImage.Load(ConnectionID, FileID: Integer): Boolean;
320   var
321    FileInfo: TFileInfo;
312  ext:      String;
322   begin
323    FileInfo := ConManager.Connection[ConnectionID].GetFileInfo(fileid);
324    if FileInfo.Extension = 'PSpc' then
# Line 369 | Line 378 | begin
378    end;
379    txmpimg := TOniImage.Create;
380    txmpimg.LoadFromTXMP(ConnectionID, PSpc.TXMP);
381 <  txmpimg.DecodeImage;
381 >  txmpimg.DecodeImageTo32bit;
382   //  txmpimg.WriteToBMP('C:\file.bmp');
383    txmpimg.GetAs32bit(txmpdata);
384   {    ShowMessage(IntToStr(txmpimg.Width)+'x'+IntToStr(txmpimg.Height));
# Line 470 | Line 479 | end;
479   function TOniImage.LoadFromTXMP(ConnectionID, FileID: Integer): Boolean;
480   var
481    img_addr: Integer;
482 +  data: TMemoryStream;
483 +  hdr: TDDSDXTHeader;
484 +  imginfo: Integer;
485 +  x,y, i: Integer;
486   begin
487    Result := True;
488    ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $8C, SizeOf(Self.FWidth), @Self.FWidth);
489    ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $8E, SizeOf(Self.FHeight), @Self.FHeight);
490 <  ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $90, SizeOf(Self.FStoreType),
491 <    @Self.FStoreType);
490 >  ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $90, SizeOf(Self.FStoreType), @Self.FStoreType);
491 >  ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $88, SizeOf(imginfo), @imginfo);
492    if ConManager.Connection[ConnectionID].DataOS = DOS_WIN then
493      ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $9C, SizeOf(img_addr), @img_addr)
494    else
# Line 483 | Line 496 | begin
496  
497    case Self.FStoreType of
498      0, 1, 2:
486    begin
487      SetLength(Self.FData, Self.FWidth * Self.FHeight * 2);
499        Self.FDepth := 16;
489    end;
500      8:
491    begin
492      SetLength(Self.FData, Self.FWidth * Self.FHeight * 4);
501        Self.FDepth := 32;
494    end;
502      9:
496    begin
497      SetLength(Self.FData, Self.FWidth * Self.FHeight div 2);
503        Self.FDepth := 16;
499    end;
504      else
505        Result := False;
506        Exit;
507    end;
508  
509    if ConManager.Connection[ConnectionID].DataOS = DOS_WIN then
510 +    ConManager.Connection[ConnectionID].LoadRawFile(fileid, $9C, TStream(data))
511 +  else
512 +    ConManager.Connection[ConnectionID].LoadRawFile(fileid, $A0, TStream(data));
513 +
514 +  with hdr do
515 +  begin
516 +    FOURCC := 'DDS ';
517 +    with SURFACEDESC2 do
518 +    begin
519 +      Size := 124;
520 +      Flags := DDSD_CAPS or DDSD_PIXELFORMAT or DDSD_WIDTH or DDSD_HEIGHT;
521 +      if FStoreType = 9 then
522 +        Flags := Flags or DDSD_LINEARSIZE
523 +      else
524 +        Flags := Flags or DDSD_PITCH;
525 +      if (imginfo and $01) > 0 then
526 +        Flags := Flags or DDSD_MIPMAPCOUNT;
527 +      Height := FHeight;
528 +      Width := FWidth;
529 +      if FStoreType = 9 then
530 +        PitchOrLinearSize := FWidth * FHeight div 2
531 +      else
532 +        PitchOrLinearSize := FWidth * FDepth div 2;
533 +      Depth := 0;
534 +      MipMapCount := 1;
535 +      x := FWidth;
536 +      y := FHeight;
537 +      while (x > 1) and (y > 1) do
538 +      begin
539 +        x := x div 2;
540 +        y := y div 2;
541 +        Inc(MipMapCount);
542 +      end;
543 +      for i := 1 to 11 do
544 +        Reserved[i] := 0;
545 +      with PIXELFORMAT do
546 +      begin
547 +        Size := 32;
548 +        if FStoreType = 9 then
549 +          Flags := DDPF_FOURCC
550 +        else
551 +          Flags := DDPF_RGB;
552 +      end;
553 +    end;
554 +  end;
555 +  LoadImageFromStream(data, FImage);
556 + {
557 +  if ConManager.Connection[ConnectionID].DataOS = DOS_WIN then
558      ConManager.Connection[ConnectionID].LoadRawFile(fileid, $9C, FData)
559    else
560      ConManager.Connection[ConnectionID].LoadRawFile(fileid, $A0, FData);
561 <
561 > }
562    Self.FDataType := [DT_OniReverted, DT_Oni];
563   end;
564  
# Line 534 | Line 586 | begin
586      link := link div 256;
587      images_decoded[i] := TOniImage.Create;
588      images_decoded[i].LoadFromTXMP(ConnectionID, link);
589 <    images_decoded[i].DecodeImage;
589 >    images_decoded[i].DecodeImageTo32bit;
590      images_decoded[i].RevertImage;
591    end;
592    SetLength(Self.FData, Self.FWidth * Self.FHeight * 4);
# Line 581 | Line 633 | end;
633  
634  
635  
636 + function TOniImage.GetImgSize(w,h, storetype: Integer): Integer;
637 + begin
638 +  case storetype of
639 +    0, 1, 2:
640 +      Result := w*h*2;
641 +    8:
642 +      Result := w*h*4;
643 +    9:
644 +      Result := Max(1, w div 4) * Max(1, h div 4) * 8;
645 +  else
646 +    Result := -1;
647 +  end;
648 + end;
649 +
650  
651   function TOniImage.GetImageDataSize(fading: Boolean): Integer;
652   var
653    size: Integer;
654    x, y: Word;
589  bpp:  Byte;
655   begin
591  case Self.FStoreType of
592    9:
593      bpp := 8;
594    0, 1, 2:
595      bpp := 16;
596    8:
597      bpp := 32;
598    else
599      Result := 0;
600      Exit;
601  end;
602
656    x    := Self.FWidth;
657    y    := Self.FHeight;
658 <  size := x * y * bpp div 8;
658 >  size := GetImgSize(x, y, FStoreType);
659    if fading then
660    begin
661      repeat
662 <      x    := x div 2;
663 <      y    := y div 2;
664 <      size := size + x * y * bpp div 8;
665 <    until (x = 1) or (y = 1);
662 >      x    := Max(x div 2, 1);
663 >      y    := Max(y div 2, 1);
664 >      size := size + GetImgSize(x, y, FStoreType);
665 >    until (x = 1) and (y = 1);
666    end;
667    Result := size;
668   end;
# Line 619 | Line 672 | end;
672  
673   procedure TOniImage.GetAsData(var Target: TStream);
674   var
622  i:      Integer;
675    revert: Boolean;
676   begin
677    //    if not (DT_Decoded32 in Self.FDataType) then
# Line 654 | Line 706 | end;
706   procedure TOniImage.GetAs32bit(var Target: TStream);
707   begin
708    if not (DT_Decoded32 in Self.FDataType) then
709 <    Self.DecodeImage;
709 >    Self.DecodeImageTo32bit;
710    if not Assigned(Target) then
711      Target := TMemoryStream.Create;
712    Target.Write(FData[0], Length(FData));
# Line 683 | Line 735 | var
735    i, x, y: Integer;
736   begin
737    if not (DT_Decoded32 in Self.FDataType) then
738 <    Self.DecodeImage;
738 >    Self.DecodeImageTo32bit;
739  
740    SetLength(Target, Self.FWidth * Self.FHeight * 3 + 54);
741    for y := 0 to Self.FHeight - 1 do

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)