+ Patches from Giulio Berna to fix endian issues, some targa issues

git-svn-id: trunk@915 -
This commit is contained in:
michael 2005-08-22 14:24:58 +00:00
parent 99ff593cf1
commit 8086f61075
9 changed files with 124 additions and 8 deletions

View File

@ -76,6 +76,40 @@ type
{54+?? : Color map : Lenght of color map is 4 bytes + the rest until the beginning of image data fixed in BFH.bfOffset} {54+?? : Color map : Lenght of color map is 4 bytes + the rest until the beginning of image data fixed in BFH.bfOffset}
TColorMap=TColorRGBA; TColorMap=TColorRGBA;
procedure SwapBMPFileHeader(var BFH : TBitMapFileHeader);
procedure SwapBMPInfoHeader(var BFI : TBitMapInfoHeader);
implementation implementation
uses FPImgCmn;
procedure SwapBMPFileHeader(var BFH : TBitMapFileHeader);
begin
with BFH do
begin
bfType:=swap(bfType);
bfSize:=swap(bfSize);
bfReserved:=swap(bfReserved);
bfOffset:=swap(bfOffset);
end;
end;
procedure SwapBMPInfoHeader(var BFI : TBitMapInfoHeader);
begin
with BFI do
begin
Size:=swap(Size);
Width:=swap(Width);
Height:=swap(Height);
Planes:=swap(Planes);
BitCount:=swap(BitCount);
Compression:=swap(Compression);
SizeImage:=swap(SizeImage);
XPelsPerMeter:=swap(XPelsPerMeter);
YPelsPerMeter:=swap(YPelsPerMeter);
ClrUsed:=swap(ClrUsed);
ClrImportant:=swap(ClrImportant);
end;
end;
end. end.

View File

@ -98,7 +98,11 @@ begin
if assigned (h) then if assigned (h) then
begin begin
Writer := h.Create; Writer := h.Create;
SaveTofile (filename, Writer); try
SaveTofile (filename, Writer);
finally
Writer.Free;
end;
break; break;
end; end;
except except
@ -186,7 +190,11 @@ begin
if assigned (h) then if assigned (h) then
begin begin
reader := h.Create; reader := h.Create;
loadfromfile (filename, reader); try
loadfromfile (filename, reader);
finally
Reader.Free;
end;
break; break;
end; end;
except except
@ -394,11 +402,12 @@ begin
// Copy extra info // Copy extra info
FExtra.Assign(Src.Fextra); FExtra.Assign(Src.Fextra);
// Copy palette if needed. // Copy palette if needed.
SetSize(0,0); { avoid side-effects in descendant classes }
UsePalette:=Src.UsePalette; UsePalette:=Src.UsePalette;
If UsePalette then If UsePalette then
begin begin
Palette.Count:=0; Palette.Count:=0;
Palette.Build(Src); Palette.Merge(Src.Palette);
end; end;
// Copy image. // Copy image.
SetSize(Src.Width,Src.height); SetSize(Src.Width,Src.height);
@ -499,8 +508,8 @@ begin
for r := 0 to h-1 do for r := 0 to h-1 do
move (FData^[r*Width], NewData^[r*AWidth], w); move (FData^[r*Width], NewData^[r*AWidth], w);
end; end;
FreeMem (FData);
end; end;
if Assigned(FData) then FreeMem(FData);
FData := NewData; FData := NewData;
inherited; inherited;
end; end;

View File

@ -17,6 +17,8 @@ unit FPImgCmn;
interface interface
function Swap(This : qword): qword;
function Swap(This : int64): int64;
function Swap(This : Longword): longword; function Swap(This : Longword): longword;
function Swap(This : integer): integer; function Swap(This : integer): integer;
function Swap(This : Word): Word; function Swap(This : Word): Word;
@ -67,6 +69,28 @@ begin
result := (AnInt SHL 16) + (TmpW1 SHL 8) + TmpB2; result := (AnInt SHL 16) + (TmpW1 SHL 8) + TmpB2;
end; end;
function Swap(This : qword): qword;
var l1, l2 : longword;
res : qword;
begin
l1:=This and $00000000FFFFFFFF;
l2:=(This and $FFFFFFFF00000000) shr 32;
l1:=swap(l1);
l2:=swap(l2);
res:=l1;
Result:=(res shl 32) + l2;
end;
function Swap(This : int64): int64;
var r,p : ^qword;
res : int64;
begin
p := @This;
r := @res;
r^ := Swap (p^);
result := res;
end;
var CRCtable : array[0..255] of longword; var CRCtable : array[0..255] of longword;
procedure MakeCRCtable; procedure MakeCRCtable;

View File

@ -132,6 +132,9 @@ Var
begin begin
Stream.Read(BFI,SizeOf(BFI)); Stream.Read(BFI,SizeOf(BFI));
{$IFDEF ENDIAN_BIG}
SwapBMPInfoHeader(BFI);
{$ENDIF}
{ This will move past any junk after the BFI header } { This will move past any junk after the BFI header }
Stream.Position:=Stream.Position-SizeOf(BFI)+BFI.Size; Stream.Position:=Stream.Position-SizeOf(BFI)+BFI.Size;
with BFI do with BFI do
@ -211,6 +214,9 @@ var
BFH:TBitMapFileHeader; BFH:TBitMapFileHeader;
begin begin
stream.Read(BFH,SizeOf(BFH)); stream.Read(BFH,SizeOf(BFH));
{$IFDEF ENDIAN_BIG}
SwapBMPFileHeader(BFH);
{$ENDIF}
With BFH do With BFH do
Result:=(bfType=BMmagic); // Just check magic number Result:=(bfType=BMmagic); // Just check magic number
end; end;

View File

@ -139,7 +139,11 @@ begin
// chunk header // chunk header
with ChunkHeader do with ChunkHeader do
begin begin
{$IFDEF ENDIAN_LITTLE}
alength := swap(CLength); alength := swap(CLength);
{$ELSE}
alength := CLength;
{$ENDIF}
ReadType := CType; ReadType := CType;
end; end;
aType := low(TChunkTypes); aType := low(TChunkTypes);
@ -160,7 +164,11 @@ begin
TheStream.Read (readCRC, sizeof(ReadCRC)); TheStream.Read (readCRC, sizeof(ReadCRC));
l := CalculateCRC (All1Bits, ReadType, sizeOf(ReadType)); l := CalculateCRC (All1Bits, ReadType, sizeOf(ReadType));
l := CalculateCRC (l, data^, alength); l := CalculateCRC (l, data^, alength);
{$IFDEF ENDIAN_LITTLE}
l := swap(l xor All1Bits); l := swap(l xor All1Bits);
{$ELSE}
l := l xor All1Bits;
{$ENDIF}
if ReadCRC <> l then if ReadCRC <> l then
raise PNGImageException.Create ('CRC check failed'); raise PNGImageException.Create ('CRC check failed');
end; end;
@ -197,7 +205,9 @@ procedure TFPReaderPNG.HandleAlpha;
var a : word; var a : word;
begin begin
move (chunk.data^[0], a, 2); move (chunk.data^[0], a, 2);
{$IFDEF ENDIAN_LITTLE}
a := swap (a); a := swap (a);
{$ENDIF}
TransparentDataValue := a; TransparentDataValue := a;
UseTransparent := True; UseTransparent := True;
end; end;
@ -212,9 +222,11 @@ procedure TFPReaderPNG.HandleAlpha;
move (data^[2], g, 2); move (data^[2], g, 2);
move (data^[4], b, 2); move (data^[4], b, 2);
end; end;
{$IFDEF ENDIAN_LITTLE}
r := swap (r); r := swap (r);
g := swap (g); g := swap (g);
b := swap (b); b := swap (b);
{$ENDIF}
d := header.bitdepth; d := header.bitdepth;
a := (TColorData(b) shl d) shl d; a := (TColorData(b) shl d) shl d;
a := a + (TColorData(g) shl d) + r; a := a + (TColorData(g) shl d) + r;
@ -407,6 +419,9 @@ begin
end; end;
end; end;
move (FCurrentLine^[DataIndex], Databytes, bytewidth); move (FCurrentLine^[DataIndex], Databytes, bytewidth);
{$IFDEF ENDIAN_BIG}
Databytes:=swap(Databytes);
{$ENDIF}
inc (DataIndex,bytewidth); inc (DataIndex,bytewidth);
end; end;
if bytewidth = 1 then if bytewidth = 1 then
@ -821,8 +836,10 @@ begin
move (chunk.data^, FHeader, sizeof(Header)); move (chunk.data^, FHeader, sizeof(Header));
with header do with header do
begin begin
{$IFDEF ENDIAN_LITTLE}
Width := swap(width); Width := swap(width);
height := swap (height); height := swap (height);
{$ENDIF}
result := (width > 0) and (height > 0) and (compression = 0) result := (width > 0) and (height > 0) and (compression = 0)
and (filter = 0) and (Interlace in [0,1]); and (filter = 0) and (Interlace in [0,1]);
end; end;

View File

@ -106,6 +106,10 @@ begin
bfReserved:=0; bfReserved:=0;
bfSize:=bfOffset+BFI.SizeImage*BytesPerPixel; bfSize:=bfOffset+BFI.SizeImage*BytesPerPixel;
end; end;
{$IFDEF ENDIAN_BIG}
SwapBMPFileHeader(BFH);
SwapBMPInfoHeader(BFI);
{$ENDIF}
Stream.seek(0,soFromBeginning); Stream.seek(0,soFromBeginning);
Stream.Write(bfh,sizeof(TBitMapFileHeader)); Stream.Write(bfh,sizeof(TBitMapFileHeader));
Stream.Write(bfi,sizeof(TBitMapInfoHeader)); Stream.Write(bfi,sizeof(TBitMapInfoHeader));

View File

@ -124,8 +124,12 @@ var chead : TChunkHeader;
begin begin
with FChunk do with FChunk do
begin begin
{$IFDEF ENDIAN_LITTLE}
chead.CLength := swap (alength); chead.CLength := swap (alength);
if (ReadType = '') then {$ELSE}
chead.CLength := alength;
{$ENDIF}
if (ReadType = '') then
if atype <> ctUnknown then if atype <> ctUnknown then
chead.CType := ChunkTypes[aType] chead.CType := ChunkTypes[aType]
else else
@ -134,7 +138,11 @@ begin
chead.CType := ReadType; chead.CType := ReadType;
c := CalculateCRC (All1Bits, ReadType, sizeOf(ReadType)); c := CalculateCRC (All1Bits, ReadType, sizeOf(ReadType));
c := CalculateCRC (c, data^, alength); c := CalculateCRC (c, data^, alength);
{$IFDEF ENDIAN_LITTLE}
crc := swap(c xor All1Bits); crc := swap(c xor All1Bits);
{$ELSE}
crc := c xor All1Bits;
{$ENDIF}
with TheStream do with TheStream do
begin begin
Write (chead, sizeof(chead)); Write (chead, sizeof(chead));
@ -381,10 +389,15 @@ var c : integer;
begin begin
with AHeader do with AHeader do
begin begin
{$IFDEF ENDIAN_LITTLE}
// problem: TheImage has integer width, PNG header longword width. // problem: TheImage has integer width, PNG header longword width.
// Integer Swap can give negative value // Integer Swap can give negative value
Width := swap (longword(TheImage.Width)); Width := swap (longword(TheImage.Width));
height := swap (longword(TheImage.Height)); height := swap (longword(TheImage.Height));
{$ELSE}
Width := TheImage.Width;
height := TheImage.Height;
{$ENDIF}
if FUseAlpha then if FUseAlpha then
c := CountAlphas c := CountAlphas
else else
@ -578,6 +591,9 @@ begin
for x := 0 to pred(TheImage.Width) do for x := 0 to pred(TheImage.Width) do
begin begin
cd := FGetPixel (x,y); cd := FGetPixel (x,y);
{$IFDEF ENDIAN_BIG}
cd:=swap(cd);
{$ENDIF}
move (cd, ScanLine^[index], FBytewidth); move (cd, ScanLine^[index], FBytewidth);
if WordSized then if WordSized then
begin begin
@ -663,7 +679,9 @@ procedure TFPWriterPNG.WritetRNS;
g := CalculateGray (SingleTransparentColor) g := CalculateGray (SingleTransparentColor)
else else
g := hi (CalculateGray(SingleTransparentColor)); g := hi (CalculateGray(SingleTransparentColor));
{$IFDEF ENDIAN_LITTLE}
g := swap (g); g := swap (g);
{$ENDIF}
move (g,ChunkDataBuffer^[0],2); move (g,ChunkDataBuffer^[0],2);
WriteChunk; WriteChunk;
end; end;
@ -675,9 +693,11 @@ procedure TFPWriterPNG.WritetRNS;
with g do with g do
if WordSized then if WordSized then
begin begin
{$IFDEF ENDIAN_LITTLE}
red := swap (red); red := swap (red);
green := swap (green); green := swap (green);
blue := swap (blue); blue := swap (blue);
{$ENDIF}
move (g, ChunkDatabuffer^[0], 6); move (g, ChunkDatabuffer^[0], 6);
end end
else else

View File

@ -97,5 +97,5 @@ begin
end; end;
initialization initialization
ImageHandlers.RegisterImageWriter ('TARGA Format', 'tgha', TFPWriterTarga); ImageHandlers.RegisterImageWriter ('TARGA Format', 'tga', TFPWriterTarga);
end. end.

View File

@ -83,6 +83,7 @@ begin
Halt(1); Halt(1);
end; end;
img := TFPMemoryImage.Create(0,0); img := TFPMemoryImage.Create(0,0);
img.UsePalette:=false;
end; end;
procedure ReadImage; procedure ReadImage;
@ -146,7 +147,8 @@ begin
if (paramcount <> 4) and (paramcount <> 3) then if (paramcount <> 4) and (paramcount <> 3) then
begin begin
writeln ('Give filename to read and to write, preceded by filetype:'); writeln ('Give filename to read and to write, preceded by filetype:');
writeln ('X for XPM, P for PNG, B for BMP (write only), J for JPEG'); writeln ('X for XPM, P for PNG, B for BMP, J for JPEG, T for TGA,');
writeln ('N for PNM (read only)');
writeln ('example: imgconv X hello.xpm P hello.png'); writeln ('example: imgconv X hello.xpm P hello.png');
writeln ('example: imgconv hello.xpm P hello.png'); writeln ('example: imgconv hello.xpm P hello.png');
writeln ('Options for'); writeln ('Options for');
@ -163,7 +165,7 @@ begin
Init; Init;
writeln ('Reading image'); writeln ('Reading image');
ReadImage; ReadImage;
writeln ('Writeing image'); writeln ('Writing image');
WriteImage; WriteImage;
writeln ('Clean up'); writeln ('Clean up');
Clean; Clean;