diff --git a/fcl/image/fpreadpnm.pp b/fcl/image/fpreadpnm.pp index 65a8411d1f..d500a5e7e1 100644 --- a/fcl/image/fpreadpnm.pp +++ b/fcl/image/fpreadpnm.pp @@ -37,7 +37,7 @@ type FHeight : Integer; protected FMaxVal : Integer; - FBPP : Byte; + FBitPP : Byte; FScanLineSize : Integer; FScanLine : PByte; procedure ReadHeader(Stream : TStream); @@ -65,14 +65,12 @@ begin begin repeat ReadBuffer(DropWhiteSpaces,1); - until not(DropWhiteSpaces in WhiteSpaces); - if DropWhiteSpaces='#' then - begin +{If we encounter comment then eate line} + if DropWhiteSpaces='#' then repeat ReadBuffer(DropWhiteSpaces,1); until DropWhiteSpaces=#10; - ReadBuffer(DropWhiteSpaces,1); - end; + until not(DropWhiteSpaces in WhiteSpaces); end; end; @@ -103,26 +101,32 @@ begin Raise Exception.Create('Not a valid PNM image.'); Stream.ReadBuffer(C,1); FBitmapType:=Ord(C)-Ord('0'); - If Not (FBitmapType in [2,3,5,6]) then + If Not (FBitmapType in [1..6]) then Raise Exception.CreateFmt('Unknown PNM subtype : %s',[C]); FWidth:=ReadInteger(Stream); FHeight:=ReadInteger(Stream); - FMaxVal:=ReadInteger(Stream); + if FBitMapType in [1,4] + then + FMaxVal:=1 + else + FMaxVal:=ReadInteger(Stream); If (FWidth<=0) or (FHeight<=0) or (FMaxVal<=0) then Raise Exception.Create('Invalid PNM header data'); case FBitMapType of - 2: FBPP:=SizeOf(Word); // Grayscale (text) - 3: FBPP:=SizeOf(Word)*3; // RGB (text) + 1: FBitPP := SizeOf(Word); + 2: FBitPP := 8 * SizeOf(Word); // Grayscale (text) + 3: FBitPP := 8 * SizeOf(Word)*3; // RGB (text) + 4: FBitPP := 1; // 1bit PP (row) 5: If (FMaxval>255) then // Grayscale (raw); - FBPP:=2 + FBitPP:= 8 * 2 else - FBPP:=1; + FBitPP:= 8; 6: if (FMaxVal>255) then // RGB (raw) - FBPP:=6 + FBitPP:= 8 * 6 else - FBPP:=3 + FBitPP:= 8 * 3 end; -// Writeln(FWidth,'x',Fheight,' Maxval: ',FMaxVal,' BPP: ',FBPP); +// Writeln(FWidth,'x',Fheight,' Maxval: ',FMaxVal,' BitPP: ',FBitPP); end; procedure TFPReaderPNM.InternalRead(Stream:TStream;Img:TFPCustomImage); @@ -135,8 +139,8 @@ var begin ReadHeader(Stream); Img.SetSize(FWidth,FHeight); - FScanLineSize:=FBPP*FWidth; - GetMem(FScanLine,FBPP*FWidth); + FScanLineSize:=FBitPP*((FWidth+7)shr 3); + GetMem(FScanLine,FScanLineSize); try for Row:=0 to img.Height-1 do begin @@ -152,10 +156,20 @@ procedure TFPReaderPNM.ReadScanLine(Row : Integer; Stream:TStream); Var P : PWord; - I : Integer; + I,j : Integer; begin Case FBitmapType of + 1 : begin + P:=PWord(FScanLine); + For I:=0 to ((FWidth+7)shr 3)-1 do + begin + P^:=0; + for j:=0 to 7 do + P^:=(P^ shr 1)or ReadInteger(Stream); + Inc(P); + end; + end; 2 : begin P:=PWord(FScanLine); For I:=0 to FWidth-1 do @@ -176,7 +190,7 @@ begin Inc(P) end; end; - 5,6 : Stream.ReadBuffer(FScanLine^,FScanLineSize); + 4,5,6 : Stream.ReadBuffer(FScanLine^,FScanLineSize); end; end; @@ -188,6 +202,33 @@ Var L : Cardinal; FHalfMaxVal : Word; + Procedure ByteBnWScanLine; + + Var + P : PByte; + I,j,x : Integer; + + begin + P:=PByte(FScanLine); + x:=7; + For I:=0 to ((FWidth+7)shr 3)-1 do + begin + L:=P^; + for j:=0 to 7 do + begin + if odd(L) + then + Img.Colors[x,Row]:=colBlack + else + Img.Colors[x,Row]:=colWhite; + L:=L shr 1; + dec(x); + end; + Inc(P); + Inc(x,16); + end; + end; + Procedure WordGrayScanLine; Var @@ -212,7 +253,7 @@ Var Var P : PWord; I : Integer; - + begin P:=PWord(FScanLine); For I:=0 to FWidth-1 do @@ -248,7 +289,7 @@ Var Inc(P); end; end; - + Procedure ByteRGBScanLine; Var @@ -276,13 +317,15 @@ begin C.Alpha:=AlphaOpaque; FHalfMaxVal:=(FMaxVal div 2); Case FBitmapType of + 1 : ; 2 : WordGrayScanline; - 3 : WordRGBSCanline; - 5 : If FBPP=1 then + 3 : WordRGBScanline; + 4 : ByteBnWScanLine; + 5 : If FBitPP=1 then ByteGrayScanLine else WordGrayScanLine; - 6 : If FBPP=3 then + 6 : If FBitPP=3 then ByteRGBScanLine else WordRGBScanLine; @@ -294,7 +337,10 @@ initialization end. { $Log$ -Revision 1.3 2004-03-03 00:03:34 michael +Revision 1.4 2004-08-26 09:33:43 mazen ++ add PBM (P4) support + +Revision 1.3 2004/03/03 00:03:34 michael + Fixed reading of pnm Revision 1.2 2003/09/30 12:26:33 mazen