ImageMagickObject creates broken PDF when using byte array

Post any defects you find in the released or beta versions of the ImageMagick software here. Include the ImageMagick version, OS, and any command-line required to reproduce the problem. Got a patch for a bug? Post it here.
Post Reply
kibeha

ImageMagickObject creates broken PDF when using byte array

Post by kibeha »

Hi, ImageMagick gurus


I'm trying to create PDF's using ImageMagickObject in asp code on an IIS 6.0 web server, streaming the PDF directly to the browser.
It works OK for single page PDF's, but multi-page PDF's are damaged and cannot open.

Testing has showed, that the problem only occurs when ImageMagickObject is converting into a byte array (to use for Response.BinaryWrite in the asp code.)
But when ImageMagickObject writes a file directly, the PDF's are created correctly and perfectly valid.

Problem has been reproduced on two servers:
Server A: Win 2003 Standard Edition SP 1, IIS 6.0, ImageMagick-6.3.1-Q16
Server B: Win 2003 Web Edition SP 1, IIS 6.0, ImageMagick-6.3.1-Q8

I have made a testcase using two small jpegs for input and creating one-page and two-page PDF's both as file and byte array.
Both PDF's created as byte array have errors - but the one-page can be opened and viewed, the two-page is too damaged and cannot be opened.


Testcase can be downloaded from http://media.thg.dk/DAT/imagemagickbug/ ... entBug.zip

Zip-file contains:
bugtest1.jpg
bugtest2.jpg
bugtest1page.asp
bugtest2page.asp
bugtest_1page_file.pdf
bugtest_1page_response.pdf
bugtest_2page_file.pdf
bugtest_2page_response.pdf

The 2 jpegs are the inputs I use for converting to pdf.
The 2 asp files contain the code for the 4 tests I create.
The 4 pdf files are the results of the 4 tests.


In bugtest1page.asp I do two tests creating a one-page pdf - one test directly to file, one test to byte array for streaming the pdf directly to the browser.


- Test 1 - convert one jpeg to a one-page pdf to file:

msg= MagickImage.convert( "C:\WWW\root\kbh\bugtest1.jpg", "C:\WWW\root\kbh\bugtest_1page_file.pdf" )

This works fine - creates a perfectly valid pdf file 16435 bytes large (bugtest_1page_file.pdf)


- Test 2 - convert one jpeg to a one-page pdf to byte array:

image2(0)="PDF:"
msg= MagickImage.convert( "C:\WWW\root\kbh\bugtest1.jpg", image2 )
<code to stream to asp response>

This works almost fine - creates a pdf file 16411 bytes large (bugtest_1page_response.pdf)
The pdf file can be opened and looks OK, but when I close Adobe Acrobat Professional, I'm prompted "Do you want to save changes to bugtest_1page_response.pdf before closing?"


In bugtest2page.asp I do two similar tests - but create a two-page pdf instead.


- Test 3 - convert two jpegs to a two-page pdf to file:

msg= MagickImage.convert( "-adjoin", "C:\WWW\root\kbh\bugtest1.jpg", "C:\WWW\root\kbh\bugtest2.jpg", "C:\WWW\root\kbh\bugtest_2page_file.pdf" )

This works fine - creates a perfectly valid two-page pdf file 34716 bytes large (bugtest_2page_file.pdf)


- Test 4 - convert two jpegs to a two-page pdf to byte array:

image2(0)="PDF:"
msg= MagickImage.convert( "-adjoin", "C:\WWW\root\kbh\bugtest1.jpg", "C:\WWW\root\kbh\bugtest2.jpg", image2 )
<code to stream to asp response>

This does not work - creates a malformed pdf file 15975 bytes large (bugtest_2page_response.pdf)
When I try to open this pdf file, I get a box "There was an error opening this document. The file is damaged and could not be repaired."


It seems to me, that creating a pdf to byte array does not write the entire result to the bytearray? Or something like that?
When creating the pdf to file, everything works perfectly - so I tentatively conclude, that the error must be in the handling of the byte array in the component?
(Or that I do something wrong, which is quite possible :? )


I hope either I can get information on what I'm doing wrong - or confirmation it is a bug and that it is "fixable" :) )
I'm developing an application (for our internal use) for opening multipage tiff files (scanned documents), add stamps to each page ("Approved","Confidential",etc), and present the result as a PDF to the user's browser.
ImageMagick is just brilliant for that purpose - except for this problem with multipage PDF creation to byte array :wink: )


Regards

Kim Berg Hansen
Senior System Developer
T. Hansen Gruppen A/S

PS. Thanks to everyone contributing to ImageMagick - it's like having a programmable PhotoShop :D )
kibeha

Reproduced using VBS script (no IIS)

Post by kibeha »

Hi, again

I've now reproduced the error using simple VBS script on my own PC (not involving IIS server and asp code.)
Also this test reproduces the error using only built-in images logo: and granite:

Here's the test VBS script :

Code: Select all


Option Explicit

' // Used to write the byte array to file
' // Thanks to www.motobit.com for the loan :-)

Function BinaryToString(Binary)
  'Antonin Foller, http://www.motobit.com
  'Optimized version of a simple BinaryToString algorithm.
  
  Dim cl1, cl2, cl3, pl1, pl2, pl3
  Dim L
  cl1 = 1
  cl2 = 1
  cl3 = 1
  L = LenB(Binary)
  
  Do While cl1<=L
    pl3 = pl3 & Chr(AscB(MidB(Binary,cl1,1)))
    cl1 = cl1 + 1
    cl3 = cl3 + 1
    If cl3>300 Then
      pl2 = pl2 & pl3
      pl3 = ""
      cl3 = 1
      cl2 = cl2 + 1
      If cl2>200 Then
        pl1 = pl1 & pl2
        pl2 = ""
        cl2 = 1
      End If
    End If
  Loop
  BinaryToString = pl1 & pl2 & pl3
End Function

' // Test code starts here

Dim ImgObj
Dim FSObj
Dim FileObj
Dim output(1)
Dim msgs

Set ImgObj = CreateObject("ImageMagickObject.MagickImage.1")
Set FSObj = CreateObject("Scripting.FileSystemObject")

' // Test 1 - one-page PDF created directly to file

msgs = ImgObj.Convert("logo:","vbstest_1page_file.pdf")

' // Test 2 - one-page PDF created to byte array

output(0)="PDF:"

msgs = ImgObj.Convert("logo:",output)

Set FileObj = FSObj.OpenTextFile("vbstest_1page_array.pdf",2,True)
FileObj.Write(BinaryToString(output))
FileObj.Close
Set FileObj = Nothing

output = Empty
Redim output(1)

' // Test 3 - two-page PDF created directly to file

msgs = ImgObj.Convert("-adjoin","logo:","granite:","vbstest_2page_file.pdf")

' // Test 4 - two-page PDF created to byte array

output(0)="PDF:"

msgs = ImgObj.Convert("-adjoin","logo:","granite:",output)

Set FileObj = FSObj.OpenTextFile("vbstest_2page_array.pdf",2,True)
FileObj.Write(BinaryToString(output))
FileObj.Close
Set FileObj = Nothing

output = Empty
Redim output(1)


' // Clean up

Set FileObj = Nothing
Set FSObj = Nothing
Set ImgObj = Nothing

WScript.Quit(0)


This creates 4 PDF files:

vbstest_1page_file.pdf - Valid one-page pdf
vbstest_1page_array.pdf - Slightly damaged one-page pdf
vbstest_2page_file.pdf - Valid two-page pdf
vbstest_2page_array.pdf - Damaged two-page pdf

Again the one-page pdf created by array can be opened but is slightly damaged, so Adobe Acrobat Professional prompts to save changes when closing the pdf file (presumably the change is a "repair" of the damaged file.)
Bug the two-page pdf created by array cannot be opened and gets the error that the file is damaged and cannot be repaired.

This is a simpler test and can be reproduced without using IIS and ASP.
I have reproduced with ImageMagick-6.3.1-Q16 on Windows XP Professional Version 2002 Service Pack 2.

Hope this can help reproduce the bug in non-IIS environment :wink:

/Kim Berg Hansen
Post Reply