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 97 by alloc, Mon Jan 22 23:05:45 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 <    function GetAsData: TByteData;
47 <    function GetAs32bit: TByteData;
48 <    procedure GetAsBMP(var Target: TByteData); overload;
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;
51 >    procedure GetAs32bit(var Target: TByteData); overload;
52      procedure GetAsBMP(var Target: TStream); overload;
53 +    procedure GetAsBMP(var Target: TByteData); overload;
54      function LoadFromBMP(filename: String): Boolean;
55      function WriteToBMP(filename: String): Boolean;
56 <    function GetMipMappedImage(var faded: TByteData): Boolean;
56 >    function GetMipMappedImage(var Target: TStream): Boolean; overload;
57 >    function GetMipMappedImage(var Target: TByteData): Boolean; overload;
58    published
59    end;
60  
# Line 52 | Line 62 | type
62   implementation
63  
64   //uses Functions;
65 <
56 <
65 > uses Img_DDSTypes;
66  
67  
68   constructor TOniImage.Create;
# Line 65 | Line 74 | begin
74    Self.FHeight    := 0;
75    Self.FDepth     := 0;
76    Self.FStoreType := 0;
77 +
78 +  InitImage(FImage);
79   end;
80  
81  
# Line 128 | Line 139 | end;
139  
140  
141  
142 < procedure TOniImage.DecodeImage;
142 > procedure TOniImage.DecodeImageTo32bit;
143   var
144    x, y:  Integer;
145    tempd: TByteData;
# Line 137 | 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 156 | 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 175 | 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 306 | Line 319 | end;
319   function TOniImage.Load(ConnectionID, FileID: Integer): Boolean;
320   var
321    FileInfo: TFileInfo;
309  ext:      String;
322   begin
323    FileInfo := ConManager.Connection[ConnectionID].GetFileInfo(fileid);
324    if FileInfo.Extension = 'PSpc' then
# Line 366 | 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 <  txmpdata := txmpimg.GetAs32bit;
383 >  txmpimg.GetAs32bit(txmpdata);
384   {    ShowMessage(IntToStr(txmpimg.Width)+'x'+IntToStr(txmpimg.Height));
385      for i:=0 to High(txmpdata) do
386        txmpimg.Data[i]:=txmpdata[i];
# Line 467 | 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 480 | Line 496 | begin
496  
497    case Self.FStoreType of
498      0, 1, 2:
483    begin
484      SetLength(Self.FData, Self.FWidth * Self.FHeight * 2);
499        Self.FDepth := 16;
486    end;
500      8:
488    begin
489      SetLength(Self.FData, Self.FWidth * Self.FHeight * 4);
501        Self.FDepth := 32;
491    end;
502      9:
493    begin
494      SetLength(Self.FData, Self.FWidth * Self.FHeight div 2);
503        Self.FDepth := 16;
496    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 531 | 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 578 | 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;
586  bpp:  Byte;
655   begin
588  case Self.FStoreType of
589    9:
590      bpp := 8;
591    0, 1, 2:
592      bpp := 16;
593    8:
594      bpp := 32;
595    else
596      Result := 0;
597      Exit;
598  end;
599
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 614 | Line 670 | end;
670  
671  
672  
673 < function TOniImage.GetAsData: TByteData;
673 > procedure TOniImage.GetAsData(var Target: TStream);
674   var
619  i:      Integer;
675    revert: Boolean;
676   begin
677    //    if not (DT_Decoded32 in Self.FDataType) then
# Line 628 | Line 683 | begin
683    end
684    else
685      revert := False;
686 <  SetLength(Result, Length(Self.FData));
687 <  for i := 0 to High(Result) do
688 <    Result[i] := Self.FData[i];
686 >  if not Assigned(Target) then
687 >    Target := TMemoryStream.Create;
688 >  Target.Write(FData[0], Length(FData));
689 >  Target.Seek(0, soFromBeginning);
690    if revert then
691      Self.RevertImage;
692   end;
693  
694 <
639 <
640 <
641 < function TOniImage.GetAs32bit: TByteData;
694 > procedure TOniImage.GetAsData(var Target: TByteData);
695   var
696 <  i: Integer;
696 >  mem: TStream;
697   begin
698 <  if not (DT_Decoded32 in Self.FDataType) then
699 <    Self.DecodeImage;
700 <  SetLength(Result, Length(Self.FData));
701 <  for i := 0 to High(Result) do
702 <    Result[i] := Self.FData[i];
698 >  mem := TMemoryStream.Create;
699 >  GetAsData(mem);
700 >  SetLength(Target, mem.Size);
701 >  mem.Read(Target[0], mem.Size);
702 >  mem.Free;
703   end;
704  
705  
706 + procedure TOniImage.GetAs32bit(var Target: TStream);
707 + begin
708 +  if not (DT_Decoded32 in Self.FDataType) then
709 +    Self.DecodeImageTo32bit;
710 +  if not Assigned(Target) then
711 +    Target := TMemoryStream.Create;
712 +  Target.Write(FData[0], Length(FData));
713 +  Target.Seek(0, soFromBeginning);
714 + end;
715 +
716 + procedure TOniImage.GetAs32bit(var Target: TByteData);
717 + var
718 +  mem: TStream;
719 + begin
720 +  mem := TMemoryStream.Create;
721 +  GetAs32bit(mem);
722 +  SetLength(Target, mem.Size);
723 +  mem.Read(Target[0], mem.Size);
724 +  mem.Free;
725 + end;
726  
727  
728   procedure TOniImage.GetAsBMP(var Target: TByteData);
# Line 662 | 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
# Line 699 | Line 772 | end;
772   procedure TOniImage.GetAsBMP(var Target: TStream);
773   var
774    data: TByteData;
775 +  streampos: Integer;
776   begin
777    GetAsBMP(data);
778 +  streampos := Target.Position;
779    Target.Write(data[0], Length(data));
780 +  Target.Seek(streampos, soFromBeginning);
781   end;
782  
783  
# Line 782 | Line 858 | end;
858  
859  
860  
861 <
786 < function TOniImage.GetMipMappedImage(var faded: TByteData): Boolean;
861 > function TOniImage.GetMipMappedImage(var Target: TByteData): Boolean;
862   var
863    i:      Integer;
864    x, y:   Word;
# Line 806 | Line 881 | begin
881  
882    x := Self.FWidth;
883    y := Self.FHeight;
884 <  SetLength(faded, x * y * Self.FDepth div 8);
884 >  SetLength(Target, x * y * Self.FDepth div 8);
885    SetLength(fadelvldata, x * y * Self.FDepth div 8);
886 <  for i := 0 to Length(faded) - 1 do
886 >  for i := 0 to Length(Target) - 1 do
887    begin
888 <    faded[i] := Self.FData[i];
888 >    Target[i] := Self.FData[i];
889      fadelvldata[i] := Self.FData[i];
890    end;
891    repeat
892      fadelvldata := Self.ResizeImage(x, y, fadelvldata);
893      x := x div 2;
894      y := y div 2;
895 <    SetLength(faded, Length(faded) + x * y * Self.FDepth div 8);
895 >    SetLength(Target, Length(Target) + x * y * Self.FDepth div 8);
896      for i := 0 to Length(fadelvldata) - 1 do
897 <      faded[Length(faded) - x * y * Self.FDepth div 8 + i] := fadelvldata[i];
897 >      Target[Length(Target) - x * y * Self.FDepth div 8 + i] := fadelvldata[i];
898    until (x = 1) or (y = 1) or ((x mod 2) = 1) or ((y mod 2) = 1);
899    if (x > 1) and (y > 1) then
900      Exit;
# Line 830 | Line 905 | begin
905   end;
906  
907  
908 + function TOniImage.GetMipMappedImage(var Target: TStream): Boolean;
909 + var
910 +  data: TByteData;
911 +  streampos: Integer;
912 + begin
913 +  Result := GetMipMappedImage(data);
914 +  if not Assigned(Target) then
915 +    Target := TMemoryStream.Create;
916 +  streampos := Target.Position;
917 +  Target.Write(data[0], Length(data));
918 +  Target.Seek(streampos, soFromBeginning);
919 + end;
920 +
921 +
922   end.

Diff Legend

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