--- oup/current/Global/OniImgClass.pas 2007/05/26 18:26:48 194 +++ oup/current/Global/OniImgClass.pas 2007/05/27 20:03:41 204 @@ -29,62 +29,27 @@ type constructor Create; procedure Free; - function Load(ConnectionID, FileID: Integer): Boolean; - function LoadFromPSpc(ConnectionID, FileID: Integer): Boolean; - function LoadFromTXMP(ConnectionID, FileID: Integer): Boolean; - function LoadFromTXMB(ConnectionID, FileID: Integer): Boolean; - procedure SaveDataToStream(MipMaps: Boolean; var Target: TStream); + function GetImageSize(MipMaps: Boolean): Integer; function LoadFromFile(filename: String): Boolean; function WriteToFile(filename: String): Boolean; - + procedure SaveDataToStream(MipMaps: Boolean; var Target: TStream); procedure DrawOnCanvas(Canvas: TCanvas; Index: Integer); - function GetImageSize(MipMaps: Boolean): Integer; + + function Load(ConnectionID, FileID: Integer): Boolean; + function LoadFromTXMP(ConnectionID, FileID: Integer): Boolean; + function LoadFromTXMB(ConnectionID, FileID: Integer): Boolean; + function LoadFromPSpc(ConnectionID, FileID: Integer): Boolean; published end; implementation -//uses Functions; uses Img_DDSTypes, ImagingComponents; -procedure TOniImage.DrawOnCanvas(Canvas: TCanvas; Index: Integer); -var - singleimg: TImageData; - rect: TRect; -begin - InitImage(singleimg); - CloneImage(FImages[Index-1], singleimg); - ConvertImage(singleimg, ifX8R8G8B8); - rect.Left := 0; - rect.Top := 0; - rect.Right := singleimg.Width - 1; - rect.Bottom := singleimg.Height - 1; - Canvas.Brush.Color := $C8D0D4; - Canvas.FillRect(Canvas.ClipRect); - DisplayImageData(Canvas, rect, singleimg, rect); - FreeImage(singleimg); -end; - - - -constructor TOniImage.Create; -begin -end; - - - -procedure TOniImage.Free; -begin - FreeImagesInArray(FImages); -end; - - - - function TOniImage.GetImage(MipGen: Integer): TImageData; begin if MipGen <= Length(FImages) then @@ -95,7 +60,6 @@ begin end; - function TOniImage.GetWidth(MipGen: Integer): Integer; begin if MipGen <= Length(FImages) then @@ -145,163 +109,141 @@ begin end; -function TOniImage.Load(ConnectionID, FileID: Integer): Boolean; + + +constructor TOniImage.Create; +begin +end; + +procedure TOniImage.Free; +begin + FreeImagesInArray(FImages); +end; + + + + +function TOniImage.GetImageSize(MipMaps: Boolean): Integer; var - FileInfo: TFileInfo; + i: Integer; begin - FileInfo := ConManager.Connection[ConnectionID].GetFileInfo(fileid); - if FileInfo.Extension = 'PSpc' then - Result := LoadFromPSpc(ConnectionID, fileid) - else if FileInfo.Extension = 'TXMB' then - Result := LoadFromTXMB(ConnectionID, fileid) - else if FileInfo.Extension = 'TXMP' then - Result := LoadFromTXMP(ConnectionID, fileid) + if Length(FImages) > 0 then + begin + Result := FImages[0].Size; + if mipmaps then + for i := 1 to High(FImages) do + Result := Result + FImages[i].Size; + end else - Result := False; + Result := -1; end; -function TOniImage.LoadFromPSpc(ConnectionID, FileID: Integer): Boolean; -type - TPoint = packed record - X, Y: Word; - end; +function TOniImage.LoadFromFile(filename: String): Boolean; +begin + Result := LoadMultiImageFromFile(filename, FImages); + if not Result then + ShowMessage('Couldn''t load image file'); +end; - TPSpc = packed record - p1: array[0..8] of TPoint; - p2: array[0..8] of TPoint; - TXMP: Integer; - end; - TPart = packed record - x_txmp, y_txmp: Word; - x_pspc, y_pspc: Word; - w, h: Word; - imgdata: TByteData; - used: Boolean; - end; -const - PartMatch: array[0..8] of Byte = (0, 3, 6, 1, 4, 7, 2, 5, 8); +function TOniImage.WriteToFile(filename: String): Boolean; +begin + Result := SaveMultiImageToFile(filename, FImages); +end; + + + +procedure TOniImage.DrawOnCanvas(Canvas: TCanvas; Index: Integer); var - x, y, pixel: Word; - i: Integer; + singleimg: TImageData; + rect: TRect; +begin + InitImage(singleimg); + CloneImage(FImages[Index-1], singleimg); + ConvertImage(singleimg, ifX8R8G8B8); + rect.Left := 0; + rect.Top := 0; + rect.Right := singleimg.Width - 1; + rect.Bottom := singleimg.Height - 1; + Canvas.Brush.Color := $C8D0D4; + Canvas.FillRect(Canvas.ClipRect); + DisplayImageData(Canvas, rect, singleimg, rect); + FreeImage(singleimg); +end; - PSpc: TPSpc; - txmpimg: TOniImage; - txmpdata: TByteData; - parts: array[0..8] of TPart; - part: Byte; - cols: array[0..2] of Word; - rows: array[0..2] of Word; - col, row: Byte; + + +procedure TOniImage.SaveDataToStream(MipMaps: Boolean; var Target: TStream); +var + images: TDynImageDataArray; + mem: TMemoryStream; + i: Integer; begin -(* - ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $08, SizeOf(PSpc), @PSpc); - PSpc.TXMP := PSpc.TXMP div 256; - if PSpc.TXMP = 0 then - begin - Result := False; + if Length(FImages) = 0 then Exit; - end; - txmpimg := TOniImage.Create; - txmpimg.LoadFromTXMP(ConnectionID, PSpc.TXMP); - txmpimg.DecodeImageTo32bit; -// txmpimg.WriteToBMP('C:\file.bmp'); - txmpimg.GetAs32bit(txmpdata); -{ ShowMessage(IntToStr(txmpimg.Width)+'x'+IntToStr(txmpimg.Height)); - for i:=0 to High(txmpdata) do - txmpimg.Data[i]:=txmpdata[i]; - txmpimg.WriteToBMP('D:\file2.bmp'); -} - with PSpc do + if MipMaps then begin - for i := 0 to 2 do - begin - cols[i] := 0; - rows[i] := 0; - end; - for i := 0 to 8 do + if Length(FImages) = 1 then begin - part := PartMatch[i]; - col := i div 3; - row := i mod 3; - if (p2[i].X > 0) or (p2[i].Y > 0) then - begin - parts[part].x_txmp := p1[i].X - 1; - parts[part].y_txmp := p1[i].Y - 1; - parts[part].x_pspc := 0; - if col > 0 then - for x := 0 to col - 1 do - Inc(parts[part].x_pspc, cols[x]); - parts[part].y_pspc := 0; - if row > 0 then - for y := 0 to row - 1 do - Inc(parts[part].y_pspc, rows[y]); - parts[part].w := p2[i].X - p1[i].X + 1; - parts[part].h := p2[i].Y - p1[i].Y + 1; - parts[part].used := True; - cols[col] := parts[part].w; - rows[row] := parts[part].h; - SetLength(parts[part].imgdata, parts[part].w * parts[part].h * 4); - for y := 0 to parts[part].h - 1 do - begin - for x := 0 to parts[part].w - 1 do - begin - for pixel := 0 to 3 do - begin - parts[part].imgdata[(y * parts[part].w + x) * 4 + pixel] := - txmpdata[((parts[part].y_txmp + y) * txmpimg.Width + - parts[part].x_txmp + x) * 4 + pixel]; - end; - end; - end; - end - else + if not GenerateMipMaps(FImages[0], 0, images) then begin - parts[part].used := False; + ShowMessage('Could not generate MipMaps'); + Exit; end; + end + else + begin + SetLength(images, Length(FImages)); + for i := 0 to High(FImages) do + CloneImage(FImages[i], images[i]); end; - - end; - - txmpimg.Free; - txmpimg := TOniImage.Create; - for i := 0 to 8 do + mem := TMemoryStream.Create; + if not SaveMultiImageToStream('dds', mem, images) then + begin + ShowMessage('Could not save images to stream'); + Exit; + end; + FreeImagesInArray(images); + end + else begin - if parts[i].used then + mem := TMemoryStream.Create; + if not SaveImageToStream('dds', mem, FImages[0]) then begin - SetLength(txmpimg.FData, Length(parts[i].imgdata)); - for pixel := 0 to High(parts[i].imgdata) do - txmpimg.Data[pixel] := parts[i].imgdata[pixel]; - txmpimg.Width := parts[i].w; - txmpimg.Height := parts[i].h; - txmpimg.StoreType := 8; - txmpimg.DataType := [DT_Decoded32]; - txmpimg.Depth := 32; - txmpimg.WriteToBMP('M:\' + IntToStr(i) + '.bmp'); + ShowMessage('Could not save image to stream'); + Exit; end; end; - txmpimg.Free; + if not Assigned(Target) then + Target := TMemoryStream.Create; + + mem.Seek(128, soFromBeginning); + Target.CopyFrom(mem, mem.Size - 128); + mem.Free; + Target.Seek(0, soFromBeginning); +end; + + + + - Self.FWidth := 0; - Self.FHeight := 0; - for i := 0 to 2 do - begin - Inc(Self.FWidth, cols[i]); - Inc(Self.FHeight, rows[i]); - end; - SetLength(Self.FData, Self.FWidth * Self.FHeight * 4); - - //Combine data parts - - Self.FDepth := 32; - Self.FStoreType := 8; - Self.FDataType := [DT_Decoded32]; - // Self.RevertImage; -*) +function TOniImage.Load(ConnectionID, FileID: Integer): Boolean; +var + FileInfo: TFileInfo; +begin + FileInfo := ConManager.Connection[ConnectionID].GetFileInfo(fileid); + if FileInfo.Extension = 'PSpc' then + Result := LoadFromPSpc(ConnectionID, fileid) + else if FileInfo.Extension = 'TXMB' then + Result := LoadFromTXMB(ConnectionID, fileid) + else if FileInfo.Extension = 'TXMP' then + Result := LoadFromTXMP(ConnectionID, fileid) + else + Result := False; end; @@ -319,7 +261,7 @@ var _storetype: Byte; _depth: Byte; begin - Result := True; + Result := False; ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $8C, SizeOf(_width), @_width); ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $8E, SizeOf(_height), @_height); ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $90, SizeOf(_storetype), @_storetype); @@ -433,38 +375,23 @@ begin else ConManager.Connection[ConnectionID].LoadRawFile(fileid, $A0, TStream(data)); -// data.Seek(0, soFromBeginning); -// data.SaveToFile('m:\test.txmp'); - data.Seek(0, soFromBeginning); - result := LoadMultiImageFromStream(data, FImages); + Result := LoadMultiImageFromStream(data, FImages); data.Free; -{ - if result then - begin - for i := 0 to High(FImages) do - begin - data := TMemoryStream.Create; - data.Write(FImages[i].Bits^, FImages[i].Size); - data.Seek(0, soFromBeginning); - data.SaveToFile('m:\test.txmp.'+IntToStr(i)); - data.Free; - end; - end; -} + if not result then begin ShowMessage('Error while loading file' + #13#10 + DetermineStreamFormat(data)); -// data.SaveToFile('m:\prob.dds'); end; end; + function TOniImage.LoadFromTXMB(ConnectionID, FileID: Integer): Boolean; var - i, x, y, x2, y2, pixelid, imgid: Integer; + i, x, y, imgid: Integer; rows, cols: Word; linkcount: Integer; link: Integer; @@ -473,6 +400,7 @@ var width, height: Word; begin + Result := False; ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $10, SizeOf(width), @width); ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $12, SizeOf(height), @height); ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $18, SizeOf(cols), @cols); @@ -507,91 +435,167 @@ begin end; for i := 0 to linkcount - 1 do images[i].Free; + Result := True; end; -procedure TOniImage.SaveDataToStream(MipMaps: Boolean; var Target: TStream); + + +function TOniImage.LoadFromPSpc(ConnectionID, FileID: Integer): Boolean; +type + TPoint = packed record + X, Y: Word; + end; + + TPSpc = packed record + p1: array[0..8] of TPoint; + p2: array[0..8] of TPoint; + TXMP: Integer; + end; + + TPart = packed record + x_txmp, y_txmp: Word; + x_pspc, y_pspc: Word; + w, h: Word; + imgdata: TImageData; + used: Boolean; + end; +const + PartMatch: array[0..8] of Byte = (0, 3, 6, 1, 4, 7, 2, 5, 8); + stretch_x: Integer = 1; + stretch_y: Integer = 1; var - images: TDynImageDataArray; - mem: TMemoryStream; + x, y: Word; i: Integer; + + PSpc: TPSpc; + txmpimg: TOniImage; + + parts: array[0..8] of TPart; + part: Byte; + cols: array[0..2] of Word; + rows: array[0..2] of Word; + col, row: Byte; + + pspcimage: TImageData; begin - if Length(FImages) = 0 then + ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $08, SizeOf(PSpc), @PSpc); + PSpc.TXMP := PSpc.TXMP div 256; + if PSpc.TXMP = 0 then + begin + Result := False; Exit; - if MipMaps then + end; + txmpimg := TOniImage.Create; + txmpimg.Load(ConnectionID, PSpc.TXMP); + CloneImage(txmpimg.Image[1], pspcimage); + txmpimg.Free; + + Result := False; + + with pspc do begin - if Length(FImages) = 1 then - begin - if not GenerateMipMaps(FImages[0], 0, images) then - begin - ShowMessage('Could not generate MipMaps'); - Exit; - end; - end - else + for i := 0 to 2 do begin - SetLength(images, Length(FImages)); - for i := 0 to High(FImages) do - CloneImage(FImages[i], images[i]); + cols[i] := 0; + rows[i] := 0; end; - mem := TMemoryStream.Create; - if not SaveMultiImageToStream('dds', mem, images) then + for i := 0 to 8 do begin - ShowMessage('Could not save images to stream'); - Exit; + part := PartMatch[i]; + col := i div 3; + row := i mod 3; + if (p2[i].X > 0) or (p2[i].Y > 0) then + begin + parts[part].x_txmp := p1[i].X;// - 1; + parts[part].y_txmp := p1[i].Y;// - 1; + parts[part].x_pspc := 0; + if col > 0 then + for x := 0 to col - 1 do + Inc(parts[part].x_pspc, cols[x]); + parts[part].y_pspc := 0; + if row > 0 then + for y := 0 to row - 1 do + Inc(parts[part].y_pspc, rows[y]); + parts[part].w := Max(p2[i].X - p1[i].X, 1);// + 1; + parts[part].h := Max(p2[i].Y - p1[i].Y, 1);// + 1; + parts[part].used := True; + cols[col] := parts[part].w; + rows[row] := parts[part].h; + + NewImage(parts[part].w, parts[part].h, pspcimage.Format, parts[part].imgdata); + + CopyRect(pspcimage, + parts[part].x_txmp, parts[part].y_txmp, parts[part].w, parts[part].h, + parts[part].imgdata, 0, 0); + end + else + begin + parts[part].used := False; + end; end; - FreeImagesInArray(images); - end - else + + end; + + for i := 0 to 8 do begin - mem := TMemoryStream.Create; - if not SaveImageToStream('dds', mem, FImages[0]) then + if parts[i].used then begin - ShowMessage('Could not save image to stream'); - Exit; +// SaveImageToFile('M:\' + IntToStr(i) + '.bmp', parts[i].imgdata); end; end; - if not Assigned(Target) then - Target := TMemoryStream.Create; -// mem.Seek(0, soFromBeginning); -// mem.SaveToFile('m:\dds.dds'); - - mem.Seek(128, soFromBeginning); - Target.CopyFrom(mem, mem.Size - 128); - mem.Free; - Target.Seek(0, soFromBeginning); -end; + SetLength(FImages, 1); + x := cols[0] + cols[1] * stretch_x + cols[2]; + y := rows[0] + rows[1] * stretch_y + rows[2]; + NewImage(x, y, pspcimage.Format, FImages[0]); -function TOniImage.LoadFromFile(filename: String): Boolean; -begin - if not LoadMultiImageFromFile(filename, FImages) then - ShowMessage('Couldn''t load image file'); -end; - - -function TOniImage.WriteToFile(filename: String): Boolean; -begin - SaveMultiImageToFile(filename, FImages); -end; - + x := 0; + for col := 0 to 2 do + begin + y := 0; + for row := 0 to 2 do + begin + part := row*3 + col; + if parts[part].used then + begin + if (row = 1) and (col = 1) then + StretchRect(parts[part].imgdata, 0, 0, parts[part].w, parts[part].h, + FImages[0], x, y, parts[part].w * stretch_x, parts[part].h * stretch_y, rfNearest) + else + if (row = 1) then + StretchRect(parts[part].imgdata, 0, 0, parts[part].w, parts[part].h, + FImages[0], x, y, parts[part].w, parts[part].h * stretch_y, rfNearest) + else + if (col = 1) then + StretchRect(parts[part].imgdata, 0, 0, parts[part].w, parts[part].h, + FImages[0], x, y, parts[part].w * stretch_x, parts[part].h, rfNearest) + else + CopyRect(parts[part].imgdata, 0, 0, parts[part].w, parts[part].h, + FImages[0], x, y ); + if row = 1 then + y := y + parts[part].h * stretch_y + else + y := y + parts[part].h; + end; + end; + if cols[col] > 0 then + begin + if (col = 1) then + x := x + parts[part].w * stretch_x + else + x := x + parts[part].w; + end; + end; + FreeImage(pspcimage); + for i := 0 to 8 do + if parts[i].used then + FreeImage(parts[i].imgdata); -function TOniImage.GetImageSize(MipMaps: Boolean): Integer; -var - i: Integer; -begin - if Length(FImages) > 0 then - begin - Result := FImages[0].Size; - if mipmaps then - for i := 1 to High(FImages) do - Result := Result + FImages[i].Size; - end - else - Result := -1; + Result := True; end; end. \ No newline at end of file