View Issue Details

IDProjectCategoryView StatusLast Update
0032005LazarusLCLpublic2017-07-19 17:07
ReporterValdas JankūnasAssigned Towp 
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
PlatformLinux 64 bitOSKubuntu 17.04OS Version
Product Version1.9 (SVN)Product Build55337 
Target VersionFixed in Version 
Summary0032005: "TLazIntfImage.LoadFromStream" throws "Invalid chunklength" after update to FPC 3.0.2
DescriptionI'm using code (see attached minimal project):

    stream := TLazarusResourceStream.Create('image_for_resource', nil);
    image := TLazIntfImage.Create(0,0);
    image.LoadFromStream(stream);

It works without problems with FPC v3.0.0 and earlier versions. After I updated it to v3.0.2 I always getting an Exception on line "LoadFromStream":

    Error while reading stream: Invalid chunklength
Steps To ReproduceCompile test project, run it and press button.
TagsNo tags attached.
Fixed in Revision
LazTarget-
Widgetset
Attached Files

Relationships

related to 0028992 new Lazarus Crash during runtime on TBitmap.CreateIntfImage; on specific files 
related to 0023850 new Lazarus Bug converting tbitmap 32 in tlazintfimage and reversing to a tbitmap again 
related to 0032013 closedMarco van de Voort FPC "TFPCustomImage.LoadFromStream" throws exception "Invalid chunklength" when compiled with FPC v3.0.2 
related to 0029990 closedMichael Van Canneyt FPC Due to changes in FCL, running empty Lazarus GUI application fails with exception "PNGImageException : Invalid chunklength". 
related to 0032025 closedMichael Van Canneyt FPC Issues with the fp-image readers 

Activities

Valdas Jankūnas

2017-06-12 22:00

reporter  

test_case.zip (130,056 bytes)

Juha Manninen

2017-06-13 12:08

developer   ~0101082

Last edited: 2017-06-13 12:08

View 2 revisions

I can reproduce with FPC 3.0.2.
I have FPC trunk compiled with debug info and decided to try with it.
The original exception happens in TFPReaderPNM.ReadHeader called from
 procedure TFPReaderPNM.InternalRead(Stream:TStream;Img:TFPCustomImage);
See, the reader code is for PNM images (whatever that is) while the image itself is PNG.
I guess the right reader class would be TFPReaderPNG, also found in fcl-images.

The example code uses TLazIntfImage (in LCL) which inherits from TFPCustomImage (in fcl-images).
Procedure LoadFromStream is in TFPCustomImage, TLazIntfImage class is not involved here.

This all means the bug is either in fcl-images lib or in the example code.
The image type goes wrong (PNM <> PNG). How should it be selected?

Juha Manninen

2017-06-13 18:30

developer   ~0101100

See a thread in fpc-pascal mailing list titled "Usage of TFPCustomImage".
I have no idea what happens but anyway the quilty party is NOT TLazIntfImage. The error happens in TFPCustomImage.LoadFromStream.

Valdas Jankūnas, can you please isolate the problem into a FPC demo (without LCL) and create a related bug report for FPC project.

Valdas Jankūnas

2017-06-13 23:43

reporter   ~0101106

Reported 0032013

Juha Manninen

2017-06-14 00:57

developer   ~0101108

> Reported 32013

Uhhh! You actually copied the same LCL application demo there.
Even the stack trace shows LCL and QT widgetset calls.
My prediction is it will not be fixed soon. Anyway I am now leaving this issue, I don't know much about graphics programming.

Valdas Jankūnas

2017-06-14 11:25

reporter   ~0101111

OK. I created FPC only example and found strangeness. There is code:
    program project1;
    uses FPImage, Classes;
    var
    fs : TStream;
    image: TFPCustomImage;
    begin
        fs := TFileStream.Create ('image_for_resource.png', fmOpenRead);
        writeln('loading "image_for_resource.png"...');
        image := TFPMemoryImage.Create(10, 10);
        image.LoadFromStream(fs);
        fs.Free;
        writeln('writing "saved_image.png"...');
        image.SaveToFile('saved_image.png');
        image.free;
    end.

When this code is compiled with FPC v3.0.0 or 3.0.2 then in both cases it always throws "FPImageException: Can't determine image type of stream".
But when that code resides in LCL application:
 - FPC v3.0.2: "TApplication.HandleException Error while reading stream: Invalid chunklength";
 - FPC v3.0.0: no exeptions and I get correct output image "saved_image.png".

Is LCL somehow involved?

wp

2017-06-14 12:06

developer   ~0101112

You must tell your program which reader should be used: add fpreadpng to uses - and you'll get the "Invalid chunklength" as well. I think that the LCL, in its unit graphics, registers all known reader/writers, therefore the fpreadpng is called internally.

Juha Manninen

2017-06-14 13:16

developer   ~0101116

Last edited: 2017-06-14 13:19

View 2 revisions

> ... unit graphics, registers all known reader/writers, therefore the fpreadpng is called internally.

According to my debugging TFPReaderPNM is called instead. Can you confirm?

wp

2017-06-14 13:26

developer   ~0101117

The FP image library is not straightforward. But if I modify your example in the following way it works without error

program project1;

uses FPImage, fpreadpng, Classes;

var
  fs : TStream;
  image: TFPCustomImage;
  reader: TFPReaderPng;
  fn: String;

  // http://www.lazarusforum.de/viewtopic.php?f=10&t=7253

begin
  fn := 'image_for_resource.png';

  writeln('loading "image_for_resource.png"...');
  image := TFPMemoryImage.Create(0, 0);
  try
    fs := TFileStream.Create(fn, fmOpenRead);
    try
      reader := TFPReaderPng.Create;
      try
        image.LoadFromStream(fs, reader);
      finally
        reader.Free;
      end;
    finally
      fs.Free;
    end;

  finally
    image.free;
  end;
end.

wp

2017-06-14 14:41

developer   ~0101119

Last edited: 2017-06-14 14:48

View 2 revisions

Juha, I did not yet look for the PNM thing because I refrained from the pain building myself a debug-fpc... (I made my test with local copies of all required units in the project folder).

I further investigated in the code above. If the reader is omitted from image.LoadFromStream (like in the OP's code) then the reader is detected automatically, and in this project png is found. So why does reading of the image with autodetection fail?

This is because in procedure TFPCustomImage.LoadFromStream (Str:TStream) (i.e. the one with autodetection) the stream position is reset back to the beginning after checking the header. But the following InternalRead seems to expect the stream to be at the next chunk (and interprets the png header as Chunk ID and Chunk size etc which results in lots of nonsense...).

          startPos := str.Position;
          ...
          reader := h.Create;
          with reader do
            try
              if CheckContents (str) then // check header
                try
                  str.Position := startPos; // reset stream pointer to start
                  FStream := str;
                  FImage := self;
                  InternalRead (str, self); // <-- crash
// ImageRead(str, self); // <-- ok
                  break;
                except
                  on e : exception do
                    msg := e.message;
                end;
            finally
              Free;
              str.Position := startPos;
            end;
          end;

If I replace the InternalRead by ImageRead (which is called from the routine if the reader is specified) then the program runs fine!

The question is why did it ever work? The ImageRead has been there for a long time. But what was changed is the resetting of the stream position (line str.Position := startPos) which was added by Michael in 0029990.

Removing the str.Position := startPos (and keeping the InternalRead) avoids the crash as well. But Michael must have had a reason to add it...

Juha, maybe we should assign this report to Michael to have him check this?

Michl

2017-06-14 14:59

developer   ~0101120

> The question is why did it ever work?

Did it? In Windows 7, I tested test_case.zip in Lazarus 1.9, 1.6.4, 1.6.2 and 1.2.0 and it doesn't run there either.

A JPG as resource runs fine everywhere.

wp

2017-06-14 15:29

developer   ~0101121

Last edited: 2017-06-14 15:31

View 2 revisions

I'm not sure whether the crash in test_case.zip is directly related to what I described with the stream positions.

A problem with my analysis could also be that the code analyzed is in fpimage.inc, and every change will affect all image formats, not only png.

Damn, why do I always forget how to build fpc on Windows?

Juha Manninen

2017-06-15 10:13

developer   ~0101142

Last edited: 2017-06-15 10:53

View 2 revisions

> Damn, why do I always forget how to build fpc on Windows?

Fpcupdeluxe did a good job for me. Just enter "-g -gl -O-" into "FPC options" field.
Fpcupdeluxe may work best when you let it install both FPC and Lazarus at the same go.
I personally installed only FPC trunk, then copied its .cfg file and then I use it by giving its full path.

wp

2017-06-15 12:29

developer   ~0101144

Juha thank you. But fpcupdeluxe hides so many things to do later when I change fpc sources. So, I preferred to go the hard way and created a batch file for me which I will keep at a holy place!

As for the PNM: Yes, I can confirm. The problem is that the reader's CheckContents method always returns true here. Therefore, every image format tested in the format detection routine after pnm is neglected! I looked in wikipedia, and they say that PNM has a typical header 'P1', or 'P2', or ... 'P7' - and I am checking this at the moment.

With this replacement and to one posted above (replace InternalRead by ImageRead) the OP's original project does no longer crash.

I'll prepare a proper patch for Michael.

José Mejuto

2017-06-15 14:55

reporter   ~0101154

Hello,

Same problem with fpreadpcx:

function TFPReaderPCX.InternalCheck(Stream: TStream): boolean;
begin
  Result := True;
end;

and fpreadtga:

function TFPReaderTarga.InternalCheck (Stream:TStream) : boolean;
begin
  Result:=True;
end;

I had reviewed several "checks" (almost all) for graphics detection both in fpc and in Lazarus and almost all are "wrong", most of them due uninitialized structure and not read data bytes verification, others move the stream but not rewind it and others rewind stream only in case of verification fail.

Reviewed in Lazarus are in this bug report https://bugs.freepascal.org/view.php?id=31160 but AFAIK almost none of them were fixed so I'll try to update my fpc and Lazarus and start to fix them.

Juha Manninen

2017-06-15 15:20

developer   ~0101157

How could the code work with FPC 3.0? Did it work? I did not test it myself.

wp

2017-06-15 23:19

developer   ~0101172

I put everything into a new report 0032025 since there are several bugs involved.

wp

2017-07-10 15:01

developer   ~0101651

Now that the underlying bug in fpc's image readers has been fixed this report is resolved as well. No change in LCL required.

Test with fpc-trunk and close if ok.

wp

2017-07-10 15:02

developer   ~0101652

Forgot to mention: the fpc report fixing this issue is 0032025.

Issue History

Date Modified Username Field Change
2017-06-12 22:00 Valdas Jankūnas New Issue
2017-06-12 22:00 Valdas Jankūnas File Added: test_case.zip
2017-06-13 10:51 Juha Manninen Relationship added related to 0028992
2017-06-13 10:54 Juha Manninen Relationship added related to 0023850
2017-06-13 12:08 Juha Manninen Note Added: 0101082
2017-06-13 12:08 Juha Manninen Note Edited: 0101082 View Revisions
2017-06-13 18:30 Juha Manninen Note Added: 0101100
2017-06-13 23:43 Valdas Jankūnas Note Added: 0101106
2017-06-14 00:57 Juha Manninen Note Added: 0101108
2017-06-14 11:25 Valdas Jankūnas Note Added: 0101111
2017-06-14 11:48 Michl Relationship added related to 0032013
2017-06-14 12:06 wp Note Added: 0101112
2017-06-14 13:16 Juha Manninen Note Added: 0101116
2017-06-14 13:19 Juha Manninen Note Edited: 0101116 View Revisions
2017-06-14 13:26 wp Note Added: 0101117
2017-06-14 14:41 wp Note Added: 0101119
2017-06-14 14:44 wp Relationship added related to 0029990
2017-06-14 14:48 wp Note Edited: 0101119 View Revisions
2017-06-14 14:59 Michl Note Added: 0101120
2017-06-14 15:29 wp Note Added: 0101121
2017-06-14 15:31 wp Note Edited: 0101121 View Revisions
2017-06-15 10:13 Juha Manninen Note Added: 0101142
2017-06-15 10:53 Juha Manninen Note Edited: 0101142 View Revisions
2017-06-15 12:29 wp Note Added: 0101144
2017-06-15 14:55 José Mejuto Note Added: 0101154
2017-06-15 15:20 Juha Manninen Note Added: 0101157
2017-06-15 23:19 wp LazTarget => -
2017-06-15 23:19 wp Note Added: 0101172
2017-06-15 23:19 wp Assigned To => wp
2017-06-15 23:19 wp Status new => acknowledged
2017-06-15 23:20 wp Relationship added related to 0032025
2017-07-10 15:01 wp Note Added: 0101651
2017-07-10 15:01 wp Status acknowledged => closed
2017-07-10 15:01 wp Resolution open => fixed
2017-07-10 15:02 wp Note Added: 0101652
2017-07-10 15:02 wp Status closed => assigned
2017-07-10 15:02 wp Resolution fixed => reopened
2017-07-10 15:02 wp Status assigned => closed
2017-07-10 15:02 wp Resolution reopened => fixed
2017-07-10 16:24 wp Status closed => assigned
2017-07-10 16:24 wp Resolution fixed => reopened
2017-07-10 16:24 wp Status assigned => resolved
2017-07-10 16:24 wp Resolution reopened => fixed
2017-07-19 17:07 Valdas Jankūnas Status resolved => closed