Results 1 to 36 of 36

Thread: [RESOLVED] VB6 Create PDF : RFC 1950 DEFLATE DIBs

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    Jan 2010
    Posts
    1,103

    Resolved [RESOLVED] VB6 Create PDF : RFC 1950 DEFLATE DIBs

    We can write PDF by Binary write... a bit complicated process. Now I am stuck how to write the Stream into file. Not so sure what is the stream? I thought it is serialized DIB bits. Headache is how to compress it. C# used DeflateStream to compress it. But How to DEFLATE using RFC 1950 in VB6?

    Code:
    MemoryStream memoryStream = new MemoryStream();
    DeflateStream deflateStream = new DeflateStream(memoryStream, CompressionMode.Compress, true);
    deflateStream.Write(arrDIBs, 0, arrDIBs.Length);
    //...
    Someone given tips:
    DeflateStream is actually implementing RFC 1951 (DEFLATE), where PDF is compressed using a compression compatible with RFC 1950. This is detailed, with a workaround, in this related Microsoft Connect bug report.
    Last edited by Jonney; Sep 15th, 2015 at 04:16 AM.

  2. #2

    Thread Starter
    Frenzied Member
    Join Date
    Jan 2010
    Posts
    1,103

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    I print everything onto a MemoryDC (Actually hMetaDC), through GetCurrentObject and GetDIBits, I can get the serialized DIB Bytes, The problem is how to compress it. Probably there's no necessary,just waste some space? or using zLib to compress it. I will try.
    Last edited by Jonney; Sep 15th, 2015 at 04:22 AM.

  3. #3

    Thread Starter
    Frenzied Member
    Join Date
    Jan 2010
    Posts
    1,103

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    Quote Originally Posted by Jonney View Post
    I print everything onto a MemoryDC (Actually hMetaDC), through GetCurrentObject and GetDIBits, I can get the serialized DIB Bytes, The problem is how to compress it. Probably there's no necessary,just waste some space? or using zLib to compress it. I will try.
    Without Deflate, the serialized DIBBits bytes are huge, If I am not wrong, for 795 pixels x 1122pixels (A4) size of image, the size of DIBBits bytes have 795x1122x3/1024 =2613KB . There're 7 pages in this pdf file, so total size is >18MB. Have to find way to compress. Does PDF accept Zlib compress and what is the compress rate?
    Last edited by Jonney; Sep 15th, 2015 at 10:25 AM.

  4. #4

    Thread Starter
    Frenzied Member
    Join Date
    Jan 2010
    Posts
    1,103

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    After using Zlib compress, the file size reduce to 140KB but failed to open by Adobe PDF reader. Adobe Reader report "Insufficient data for an image". Not sure what is going wrong. Does PDF accept Zlib compress?

    Here is the Text part:

    Code:
    %PDF-1.1
    
    1 0 obj
    <<
    /Type /Catalog
    /Pages 2 0 R
    >>
    endobj
    
    2 0 obj
    <<
    /Type /Pages
    /Count 7
    /MediaBox [0 0 595.2756 841.8898]
    /Kids [
    11 0 R
    14 0 R
    17 0 R
    20 0 R
    23 0 R
    26 0 R
    29 0 R
    ]
    /Resources 3 0 R
    >>
    endobj
    
    3 0 obj
    <<
    /ProcSet [/PDF /Text /ImageC]
    /XObject <<
    /Image0 4 0 R
    /Image1 5 0 R
    /Image2 6 0 R
    /Image3 7 0 R
    /Image4 8 0 R
    /Image5 9 0 R
    /Image6 10 0 R
    >>
    >>
    endobj
    
    4 0 obj
    <<
    /Type /XObject
    /Subtype /Image
    /Name /Image0
    /Width 794
    /Height  1123
    /BitsPerComponent 8
    /ColorSpace /DeviceRGB
    /Filter /FlateDecode
    /Length 19896
    >>stream
    X
    Code:
    endstream
    endobj
    
    11 0 obj
    <<
    /Type /Page
    /Parent 2 0 R
    /Contents [12 0 R]
    >>
    endobj
    
    12 0 obj
    <<
    /Length 13 0 R
    >>
    stream
    q
    595.2756 0 0 841.8898 0.0000 0.0000 cm
    /Image0 Do
    Q
    endstream
    endobj
    
    13 0 obj
    54
    endobj
    
    14 0 obj
    <<
    /Type /Page
    /Parent 2 0 R
    /Contents [15 0 R]
    >>
    endobj
    
    15 0 obj
    <<
    /Length 16 0 R
    >>
    stream
    q
    595.2756 0 0 841.8898 0.0000 0.0000 cm
    /Image1 Do
    Q
    endstream
    endobj
    
    16 0 obj
    54
    endobj
    
    17 0 obj
    <<
    /Type /Page
    /Parent 2 0 R
    /Contents [18 0 R]
    >>
    endobj
    
    18 0 obj
    <<
    /Length 19 0 R
    >>
    stream
    q
    595.2756 0 0 841.8898 0.0000 0.0000 cm
    /Image2 Do
    Q
    endstream
    endobj
    
    19 0 obj
    54
    endobj
    
    20 0 obj
    <<
    /Type /Page
    /Parent 2 0 R
    /Contents [21 0 R]
    >>
    endobj
    
    21 0 obj
    <<
    /Length 22 0 R
    >>
    stream
    q
    595.2756 0 0 841.8898 0.0000 0.0000 cm
    /Image3 Do
    Q
    endstream
    endobj
    
    22 0 obj
    54
    endobj
    
    23 0 obj
    <<
    /Type /Page
    /Parent 2 0 R
    /Contents [24 0 R]
    >>
    endobj
    
    24 0 obj
    <<
    /Length 25 0 R
    >>
    stream
    q
    595.2756 0 0 841.8898 0.0000 0.0000 cm
    /Image4 Do
    Q
    endstream
    endobj
    
    25 0 obj
    54
    endobj
    
    26 0 obj
    <<
    /Type /Page
    /Parent 2 0 R
    /Contents [27 0 R]
    >>
    endobj
    
    27 0 obj
    <<
    /Length 28 0 R
    >>
    stream
    q
    595.2756 0 0 841.8898 0.0000 0.0000 cm
    /Image5 Do
    Q
    endstream
    endobj
    
    28 0 obj
    54
    endobj
    
    29 0 obj
    <<
    /Type /Page
    /Parent 2 0 R
    /Contents [30 0 R]
    >>
    endobj
    
    30 0 obj
    <<
    /Length 31 0 R
    >>
    stream
    q
    595.2756 0 0 841.8898 0.0000 0.0000 cm
    /Image6 Do
    Q
    endstream
    endobj
    
    31 0 obj
    54
    endobj
    
    32 0 obj
    <<
    /Title (Sample)
    /Producer (Grid.ActiveX)
    /CreationDate (D:20150915233152)
    >>
    endobj
    
    xref
    0 33
    0000000000 65535 f 
    0000000010 00000 n 
    0000000060 00000 n 
    0000000214 00000 n 
    0000000387 00000 n 
    0000020470 00000 n 
    0000040553 00000 n 
    0000060636 00000 n 
    0000080719 00000 n 
    0000100802 00000 n 
    0000120885 00000 n 
    0000140969 00000 n 
    0000141037 00000 n 
    0000141146 00000 n 
    0000141166 00000 n 
    0000141234 00000 n 
    0000141343 00000 n 
    0000141363 00000 n 
    0000141431 00000 n 
    0000141540 00000 n 
    0000141560 00000 n 
    0000141628 00000 n 
    0000141737 00000 n 
    0000141757 00000 n 
    0000141825 00000 n 
    0000141934 00000 n 
    0000141954 00000 n 
    0000142022 00000 n 
    0000142131 00000 n 
    0000142151 00000 n 
    0000142219 00000 n 
    0000142328 00000 n 
    0000142348 00000 n 
    trailer
    <<
    /Size 33
    /Root 1 0 R
    /Info 32 0 R
    >>
    startxref
    142462
    %%EOF
    Last edited by Jonney; Sep 15th, 2015 at 11:07 AM.

  5. #5
    MS SQL Powerposter szlamany's Avatar
    Join Date
    Mar 2004
    Location
    Connecticut
    Posts
    18,263

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    this section from the PDF spec talks about the compression - is this what you understood it to be?

    7.4.4LZWDecode and FlateDecode Filters
    7.4.4.1General
    The LZWDecode and (PDF 1.2) FlateDecode filters have much in common and are discussed together in this sub-clause. They decode data that has been encoded using the LZW or Flate data compression method, respectively:
    •LZW (Lempel-Ziv-Welch) is a variable-length, adaptive compression method that has been adopted as one of the standard compression methods in the Tag Image File Format (TIFF) standard. For details on LZW encoding see 7.4.4.2, "Details of LZW Encoding."
    •The Flate method is based on the public-domain zlib/deflate compression method, which is a variable-length Lempel-Ziv adaptive compression method cascaded with adaptive Huffman coding. It is fully defined in Internet RFCs 1950, ZLIB Compressed Data Format Specification, and 1951, DEFLATE Compressed Data Format Specification (see the Bibliography).

    *** Read the sticky in the DB forum about how to get your question answered quickly!! ***

    Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".

    Some Informative Links:
    [ SQL Rules to Live By ] [ Reserved SQL keywords ] [ When to use INDEX HINTS! ] [ Passing Multi-item Parameters to STORED PROCEDURES ]
    [ Solution to non-domain Windows Authentication ] [ Crazy things we do to shrink log files ] [ SQL 2005 Features ] [ Loading Pictures from DB ]

    MS MVP 2006, 2007, 2008

  6. #6

    Thread Starter
    Frenzied Member
    Join Date
    Jan 2010
    Posts
    1,103

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    Quote Originally Posted by szlamany View Post
    this section from the PDF spec talks about the compression - is this what you understood it to be?
    Do you know how to implement "ZLIB Compressed Data Format Specification, and 1951, DEFLATE Compressed Data Format Specification" in VB6?

  7. #7
    MS SQL Powerposter szlamany's Avatar
    Join Date
    Mar 2004
    Location
    Connecticut
    Posts
    18,263

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    I do not and google did not help me much just now.

    Do you have a copy of the PDF spec document?

    *** Read the sticky in the DB forum about how to get your question answered quickly!! ***

    Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".

    Some Informative Links:
    [ SQL Rules to Live By ] [ Reserved SQL keywords ] [ When to use INDEX HINTS! ] [ Passing Multi-item Parameters to STORED PROCEDURES ]
    [ Solution to non-domain Windows Authentication ] [ Crazy things we do to shrink log files ] [ SQL 2005 Features ] [ Loading Pictures from DB ]

    MS MVP 2006, 2007, 2008

  8. #8
    MS SQL Powerposter szlamany's Avatar
    Join Date
    Mar 2004
    Location
    Connecticut
    Posts
    18,263

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs


    *** Read the sticky in the DB forum about how to get your question answered quickly!! ***

    Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".

    Some Informative Links:
    [ SQL Rules to Live By ] [ Reserved SQL keywords ] [ When to use INDEX HINTS! ] [ Passing Multi-item Parameters to STORED PROCEDURES ]
    [ Solution to non-domain Windows Authentication ] [ Crazy things we do to shrink log files ] [ SQL 2005 Features ] [ Loading Pictures from DB ]

    MS MVP 2006, 2007, 2008

  9. #9

    Thread Starter
    Frenzied Member
    Join Date
    Jan 2010
    Posts
    1,103

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    Quote Originally Posted by szlamany View Post
    I will read...
    Any one know how to implement "Deflate algorithm" in VB6? Simply use Zlib doesn't work.

    Code:
    Public Enum CompressionLevels
        COMPRESS_NONE = 0
        COMPRESS_BEST_SPEED = 1
        '//-- note that levels 2-8 exist, too
        COMPRESS_BEST = 9
        COMPRESS_DEFAULT = -1
    End Enum
    Private Declare Function compress2 Lib "zlib.dll" (Dest As Any, destLen As Any, src As Any, ByVal srcLen As Long, ByVal level As Long) As Long
    
    Public Function CompressByteArray(TheData() As Byte, CompressionLevel As CompressionLevels) As Long
    Dim result          As Long
    Dim bufferSize      As Long
    Dim TempBuffer()    As Byte
    
    Dim OriginalSize As Long, CompressedSize As Long
    OriginalSize = UBound(TheData) + 1
    
    '//-- Allocate memory for byte array
    bufferSize = UBound(TheData) + 1
    bufferSize = bufferSize + (bufferSize * 0.01) + 12
    ReDim TempBuffer(bufferSize)
    
    '//-- Compress byte array (data)
    result = compress2(TempBuffer(0), bufferSize, TheData(0), UBound(TheData) + 1, CompressionLevel)
    
    '//-- Truncate to compressed size
    ReDim Preserve TheData(bufferSize - 1)
    CopyMemory TheData(0), TempBuffer(0), bufferSize
    
    '//-- Cleanup
    Erase TempBuffer
    
    '//-- Set property
    CompressedSize = UBound(TheData) + 1
    
    '//-- Return Error/Success
    CompressByteArray = result
    
    End Function

  10. #10
    Fanatic Member
    Join Date
    Aug 2013
    Posts
    806

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    Jonney, I think this link might help:

    http://www.codeproject.com/Articles/...ain-Text-using

    You can't use the simple "compress" function in zLib. This creates a zLib stream, which is a deflate stream with a zLib wrapper around it.

    You need to use the underlying deflate functions (like deflateInit(), deflate(), deflateEnd()) to get a deflate stream without the zLib wrapper. That codeproject link should demonstrate how to do this with PDF-specific data.

    EDIT: Actually, on closer inspection, I think Jonney was originally correct. A zLib stream should be used, per the PDF spec (zLib compression is RFC 1950). The default compress() function should work just fine.
    Last edited by Tanner_H; Sep 16th, 2015 at 08:05 AM.
    Check out PhotoDemon, a pro-grade photo editor written completely in VB6. (Full source available at GitHub.)

  11. #11
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    Any one know how to implement "Deflate algorithm" in VB6? Simply use Zlib doesn't work.
    Depends on which zlib you are using. There's a VB stdCall version out and about and the cDecl version provided by ZLib's website. You cannot call the cDecl directly in VB and expect success. cDecl DLLs require a bit of extra code to have them work properly.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  12. #12

    Thread Starter
    Frenzied Member
    Join Date
    Jan 2010
    Posts
    1,103

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    Quote Originally Posted by Tanner_H View Post
    Jonney, I think this link might help:

    http://www.codeproject.com/Articles/...ain-Text-using

    You can't use the simple "compress" function in zLib. This creates a zLib stream, which is a deflate stream with a zLib wrapper around it.

    You need to use the underlying deflate functions (like deflateInit(), deflate(), deflateEnd()) to get a deflate stream without the zLib wrapper. That codeproject link should demonstrate how to do this with PDF-specific data.
    I have downloaded the demo, the demo itself doesn't work to decode (decompress) a normal pdf file. I extract the compress park, it did compress but the pdf still failed to open with 'insufficient image data'. Not sure my code got problem or the compress function got problem.

    I have to make sure my code works:
    'packed DIB
    Code:
    Public Function SerializeDIB(ByVal hdc As Long, ByVal lImageWidth As Long, lImageHeight As Long, ByRef DIBBits() As Byte) As Boolean
       
       Dim lbmpHandle As Long
       lbmpHandle = GetCurrentObject(hdc, 7) 'OBJ_BITMAP = 7
       
       If lbmpHandle = 0 Then
          SerializeDIB = False
          Exit Function
       End If
       
       Dim bmi As BITMAPINFO
       With bmi
           .Header.biSize = 40
           .Header.biBitCount = 32
           .Header.biCompression = 0
           .Header.biPlanes = 1
           .Header.biWidth = lImageWidth
           .Header.biHeight = lImageHeight
           .Header.biSizeImage = lImageWidth * lImageHeight * 4
           Dim ImageData() As Byte
           ReDim ImageData(.Header.biSizeImage - 1)
       End With
       
       If GetDIBits(hdc, lbmpHandle, 0, lImageHeight, ImageData(0), bmi, DIB_RGB_COLORS) = 0 Then
          SerializeDIB = False
          Exit Function
       End If
       
       Dim i As Long, j As Long, k As Long
       Dim num As Long
       ReDim DIBBits(lImageWidth * lImageHeight * 3 - 1)
       For i = lImageHeight - 1 To 0 Step -1
           num = i * lImageWidth * 4
           For j = 0 To lImageWidth - 1
               For k = num + 2 To num Step -1
                   Dim num4 As Long
                   DIBBits(num4) = ImageData(k)
                   num4 = num4 + 1
               Next
               num = num + 4
           Next
       Next
       
       SerializeDIB = True
       
    End Function

  13. #13

    Thread Starter
    Frenzied Member
    Join Date
    Jan 2010
    Posts
    1,103

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    Quote Originally Posted by LaVolpe View Post
    Depends on which zlib you are using. There's a VB stdCall version out and about and the cDecl version provided by ZLib's website. You cannot call the cDecl directly in VB and expect success. cDecl DLLs require a bit of extra code to have them work properly.
    I don't know how to implement.

    .NET code:
    Code:
    MemoryStream memoryStream = new MemoryStream();
    DeflateStream deflateStream = new DeflateStream(memoryStream, CompressionMode.Compress, true);
    deflateStream.Write(DIBBits, 0, DIBBits.Length);
    deflateStream.Close();
    deflateStream.Dispose();
    DIBBits = memoryStream.ToArray();
    memoryStream.Close();
    memoryStream.Dispose();

  14. #14
    PowerPoster Arnoutdv's Avatar
    Join Date
    Oct 2013
    Posts
    5,904

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    Did you have a look at this tutorial?
    http://www.vb6.us/tutorials/visual-basic-tutorial-pdf

  15. #15
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,253

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    Quote Originally Posted by Jonney View Post
    I print everything onto a MemoryDC (Actually hMetaDC), through GetCurrentObject and GetDIBits, I can get the serialized DIB Bytes, ...
    I don't understand, why you do not use the MetaFile (you're already printing to),
    and just play it on a PDF-Printer-Driver (a PDF-PrinterDrivers hDC)?

    This way (since PlayEnhMetaFile would only "re-play" its stored GDI-commands), you would end up with:
    - a much smaller size of your PDF
    - selectable, searchable, copyable Text in your PDF-Reader

    Storing "one huge Bitmap per PDF-Page" (compressed or not) - is not a good idea IMO.


    Olaf

  16. #16

    Thread Starter
    Frenzied Member
    Join Date
    Jan 2010
    Posts
    1,103

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    Quote Originally Posted by Schmidt View Post
    I don't understand, why you do not use the MetaFile (you're already printing to),
    and just play it on a PDF-Printer-Driver (a PDF-PrinterDrivers hDC)?

    This way (since PlayEnhMetaFile would only "re-play" its stored GDI-commands), you would end up with:
    - a much smaller size of your PDF
    - selectable, searchable, copyable Text in your PDF-Reader

    Storing "one huge Bitmap per PDF-Page" (compressed or not) - is not a good idea IMO.


    Olaf
    It is because We need ExportToPDF function exposed to user, instead open the preview form then select the PDF creator Printer to generate PDF...

  17. #17

    Thread Starter
    Frenzied Member
    Join Date
    Jan 2010
    Posts
    1,103

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    Quote Originally Posted by Arnoutdv View Post
    Did you have a look at this tutorial?
    http://www.vb6.us/tutorials/visual-basic-tutorial-pdf
    I am looking that...
    1. too too slow
    2. 'out of memory' and some other errors reported by adobe reader
    3. not Unicode
    4. The Image doesn't work (PDFImage & PDFParseJPG) and no Compress.

  18. #18

    Thread Starter
    Frenzied Member
    Join Date
    Jan 2010
    Posts
    1,103

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    OK. I change "/Filter /FlateDecode" & vbLf to "/Filter /DCTDecode" & vbLf so that we can use JPEG to compress instead RFC-1950. Now the PDF display just fine though we have to pay slower speed ,bigger space and lower resolution.

    Pending for solution for Deflate zLib.
    Last edited by Jonney; Sep 16th, 2015 at 03:30 AM.

  19. #19

    Thread Starter
    Frenzied Member
    Join Date
    Jan 2010
    Posts
    1,103

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    @Lavolpe:
    I remember you had some code to extract pictures from PDF. Did you use zLib or else to decode the streams?

    FYI:
    http://www.p2501.ch/pdf-howto/grundl...ien/bilder/png is quite informative.
    Last edited by Jonney; Sep 15th, 2015 at 10:57 PM.

  20. #20
    Fanatic Member
    Join Date
    Aug 2013
    Posts
    806

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    Jonney, I need to apologize. On closer inspection of the PDF spec, I think you were originally correct. A pure zLib stream *can* be used (zLib compression is RFC 1950; I should have remembered this). So you should have been okay with the original zLib compress() function. I'm sorry for my bad advice.

    I'm glad you got /DCTDecode to work, but it's strange to me that /FlateDecode didn't work with your original code.

    The link you share in the previous comment (from p2501.ch) seems to suggest that PNGs work okay inside a PDF. PNGs use FlateDecode, but on a row-by-row basis instead of one huge compression for the entire file. Have you tried its suggestion for PNG format data inside a PDF?
    Check out PhotoDemon, a pro-grade photo editor written completely in VB6. (Full source available at GitHub.)

  21. #21

    Thread Starter
    Frenzied Member
    Join Date
    Jan 2010
    Posts
    1,103

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    Quote Originally Posted by Tanner_H View Post
    Jonney, I need to apologize. On closer inspection of the PDF spec, I think you were originally correct. A pure zLib stream *can* be used (zLib compression is RFC 1950; I should have remembered this). So you should have been okay with the original zLib compress() function. I'm sorry for my bad advice.

    I'm glad you got /DCTDecode to work, but it's strange to me that /FlateDecode didn't work with your original code.

    The link you share in the previous comment (from p2501.ch) seems to suggest that PNGs work okay inside a PDF. PNGs use FlateDecode, but on a row-by-row basis instead of one huge compression for the entire file. Have you tried its suggestion for PNG format data inside a PDF?
    I also notice PDF support PNG. I will try. Thanks for advice.
    About zLib, I haven't yet made it work. one possible cause is mistake in my code to convert bitmap to PDF indexed bitmap image or my adler32 checksum algorithm (involved BugInteger,VB6 lack of good library). Have you look at the above code "SerializeDIB" ? I will try to use GDI+ API.
    Last edited by Jonney; Sep 16th, 2015 at 08:53 AM.

  22. #22
    MS SQL Powerposter szlamany's Avatar
    Join Date
    Mar 2004
    Location
    Connecticut
    Posts
    18,263

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    I posted that spec link and the quote (I should have included more in the quote) so you could see that zlib is what 1950 is and that deflate is what 1951 is. I believe it went on to say that deflate was not too small (as you noticed).

    I use PDFSharp to create PDF's - making a graphics object and writing text to it. Is that a poor method of making PDF's? I was about to work in a LOGO for a client - I thought since I was using PDFSharp and graphics objects that would be a piece of cake.

    *** Read the sticky in the DB forum about how to get your question answered quickly!! ***

    Please remember to rate posts! Rate any post you find helpful - even in old threads! Use the link to the left - "Rate this Post".

    Some Informative Links:
    [ SQL Rules to Live By ] [ Reserved SQL keywords ] [ When to use INDEX HINTS! ] [ Passing Multi-item Parameters to STORED PROCEDURES ]
    [ Solution to non-domain Windows Authentication ] [ Crazy things we do to shrink log files ] [ SQL 2005 Features ] [ Loading Pictures from DB ]

    MS MVP 2006, 2007, 2008

  23. #23
    Fanatic Member
    Join Date
    Aug 2013
    Posts
    806

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    Quote Originally Posted by Jonney View Post
    About zLib, I haven't yet made it work. one possible cause is mistake in my code to convert bitmap to PDF indexed bitmap image or my adler32 checksum algorithm (involved BugInteger,VB6 lack of good library). Have you look at the above code "SerializeDIB" ? I will try to use GDI+ API.
    For adler32, you can just use zLib. Here is the function declaration (I'll include the zLib crc32 function as well):

    Code:
    Private Declare Function adler32 Lib "zlibwapi.dll" (ByVal adlerStart As Long, ByRef srcBuffer As Any, ByVal srcLength As Long) As Long
    Private Declare Function crc32 Lib "zlibwapi.dll" (ByVal crcStart As Long, ByRef srcBuffer As Any, ByVal srcLength As Long) As Long
    Like other CRC algorithms, adler32 takes a starting polynomial. zLib suggests that you let zLib generate this for you, which you can do like this:

    Code:
    Dim polyStart as Long
    polyStart = adler32(0&, ByVal 0&, 0&)
    
    'Now call adler32 on your array, passing polyStart as the first parameter, something like:
    adlerChecksum = adler32(polyStart, inputArray(), sizeOfArrayInBytes)
    I haven't looked at your SerializeDIB function yet, but will try to examine it later today.
    Check out PhotoDemon, a pro-grade photo editor written completely in VB6. (Full source available at GitHub.)

  24. #24
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,253

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    Quote Originally Posted by szlamany View Post
    I posted that spec link and the quote (I should have included more in the quote) so you could see that zlib is what 1950 is and that deflate is what 1951 is. I believe it went on to say that deflate was not too small (as you noticed).

    I use PDFSharp to create PDF's - making a graphics object and writing text to it. Is that a poor method of making PDF's? I was about to work in a LOGO for a client - I thought since I was using PDFSharp and graphics objects that would be a piece of cake.
    Jonney doesn't want to introduce "larger dependencies" into his
    PDF-Exporting solution apparently.

    Writing PDFs will be equally easy as the PDFSharp-solution, when he'd use the
    vbRichClient5 (which is by quite a degree smaller than the .NET-dependency).

    The size of the ZLib-Binary (which is a dependency to ship as well) is apparently
    still in a range which is acceptable (even though the surrounding VB6-code
    would be much larger and less well-tested than working against a larger lib).

    @Jonney
    Let me know, when I shall show you an example, how to do the PDF-Export
    over the RC5.

    Olaf

  25. #25
    Fanatic Member
    Join Date
    Aug 2013
    Posts
    806

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    Quote Originally Posted by szlamany View Post
    I posted that spec link and the quote (I should have included more in the quote) so you could see that zlib is what 1950 is and that deflate is what 1951 is. I believe it went on to say that deflate was not too small (as you noticed).
    Yeah, apologies for missing that. The Adobe documentation is confusing because they call it DEFLATE, but they seem to mean DEFLATE-AS-IMPLEMENTED-BY-ZLIB. A zLib stream is just a DEFLATE stream with a short header and an adler checksum at the end.

    @Jonney - speaking of this, are you sure you need to calculate your own Adler checksum? I'm not familiar with PDF requirements, but a zLib stream already has a checksum at the end (that's one of the things that makes it different from a plain DEFLATE stream). Maybe you don't need that extra step in your code, because zLib has already done it for you.

    Microsoft, however, would need to tack that onto the end of its DeflateStream function to convert their plain DEFLATE stream into a zLib stream.
    Check out PhotoDemon, a pro-grade photo editor written completely in VB6. (Full source available at GitHub.)

  26. #26

    Thread Starter
    Frenzied Member
    Join Date
    Jan 2010
    Posts
    1,103

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    Quote Originally Posted by Tanner_H View Post
    @Jonney - speaking of this, are you sure you need to calculate your own Adler checksum? I'm not familiar with PDF requirements, but a zLib stream already has a checksum at the end (that's one of the things that makes it different from a plain DEFLATE stream). Maybe you don't need that extra step in your code, because zLib has already done it for you.
    We need to put 4 bytes of Adler32Checksum which is UInt32 at the end of chunk.
    From what I tested, If we just screw in JPEG binary file into PDF and use switch /DCTDecode, the checksum is not important, I put wrong 4 bytes,PDF reader can read no problem. But I am sure for Filter /FlateDecode because my code doesn't functioning at this moment.

    Microsoft, however, would need to tack that onto the end of its DeflateStream function to convert their plain DEFLATE stream into a zLib stream.
    I am not so understand zLib...But I will use Reflector to look MS how to implement .NET DeflateStream.

  27. #27

    Thread Starter
    Frenzied Member
    Join Date
    Jan 2010
    Posts
    1,103

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    Quote Originally Posted by Schmidt View Post
    Jonney doesn't want to introduce "larger dependencies" into his
    PDF-Exporting solution apparently.
    I almost reach the last Kilometer. But the zLib block me.
    There're many open source in Java and .NET or C++, but none of VB6.
    For Java and C# guys, they are lucky to have good and boost library for easy life, but for VB6...
    you can't expect we are perfect on everything...

    Writing PDFs will be equally easy as the PDFSharp-solution, when he'd use the
    vbRichClient5 (which is by quite a degree smaller than the .NET-dependency).

    Olaf
    I know RichClient5 is very powerful. The only problem is no a big hero or a good team to lead us on the road, Only
    your effort and promotion is not strong enough...
    For experienced/senior programmer (like fafalone), they can use APIs or MS library (like GDI+) to write most of codes.
    For junior or intermediate(like me), they have no idea how to use RC5. They are afraid of learning new things. They need enough samples, not a document.

    The size of the ZLib-Binary (which is a dependency to ship as well) is apparently
    still in a range which is acceptable (even though the surrounding VB6-code
    would be much larger and less well-tested than working against a larger lib).
    Can you please show us how the zLib implement in RC5?

    @Jonney
    Let me know, when I shall show you an example, how to do the PDF-Export
    over the RC5.
    Of course, You are always welcome to show us RC5 in my thread, Thanks you sir!

  28. #28
    Fanatic Member
    Join Date
    Aug 2013
    Posts
    806

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    Quote Originally Posted by Jonney View Post
    We need to put 4 bytes of Adler32Checksum which is UInt32 at the end of chunk.
    Sorry to keep asking, but are you sure about this? Is that in the PDF spec?

    Here's why I ask. A zLib stream looks like this:

    (2 byte header)(DEFLATE stream)(4 byte adler32 checksum)

    So the result of a zLib compress() call is a DEFLATE stream, with a two-byte header prepended and an adler32 checksum already appended.

    From this link (among others), others have verified that you can turn a zLib stream into a DEFLATE stream (identical to the .NET DeflateStream function) by removing the first 2 bytes and last 4 bytes. To quote that link:

    SOLVED
    To handle the raw deflate and inflate, without header and checksum, the following things needed to happen:
    On deflate/compress: strip the first two bytes (header) and the last four bytes (checksum) [of the zLib stream].
    This gives you a way to easily convert a zLib stream to a pure DEFLATE stream, if you need to. (I don't think you need to for PDFs - I think the zLib stream is what you need, as we've discussed.) From this, I also don't think you need to calculate your own adler32 checksum. The result of a zLib compress() call already has one at the end.

    Now for your DIB serialization. I think it has some issues. Here is an easier solution. (It might not be perfect because I am writing it on a Mac without testing it, but hopefully you get the idea):

    Code:
    Dim x As Long, y As Long
    
    Dim lineNewArray As Long, lineOldArray as Long
    
    ReDim DIBBits(lImageWidth * lImageHeight * 3 - 1) as Byte
    
    For y = 0 to lImageHeight - 1
    
       lineOldArray = ((lImageHeight - 1) - y) * lImageWidth * 4
       lineNewArray = y * lImageWidth * 3
    
       For x = 0 To lImageWidth - 1
           
           DIBBits(lineNewArray + (x * 3) + 2) = ImageData(lineOldArray + (x * 4))
           DIBBits(lineNewArray + (x * 3) + 1) = ImageData(lineOldArray + (x * 4) + 1)
           DIBBits(lineNewArray + (x * 3)) = ImageData(lineOldArray + (x * 4) + 2)
    
       Next x
    Next y
    Try the result of that serialize approach with a pure zLib stream, and see if it changes anything.
    Check out PhotoDemon, a pro-grade photo editor written completely in VB6. (Full source available at GitHub.)

  29. #29

    Thread Starter
    Frenzied Member
    Join Date
    Jan 2010
    Posts
    1,103

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    Quote Originally Posted by Tanner_H View Post
    Sorry to keep asking, but are you sure about this? Is that in the PDF spec?

    Here's why I ask. A zLib stream looks like this:

    (2 byte header)(DEFLATE stream)(4 byte adler32 checksum)

    So the result of a zLib compress() call is a DEFLATE stream, with a two-byte header prepended and an adler32 checksum already appended.

    From this link (among others), others have verified that you can turn a zLib stream into a DEFLATE stream (identical to the .NET DeflateStream function) by removing the first 2 bytes and last 4 bytes. To quote that link:



    This gives you a way to easily convert a zLib stream to a pure DEFLATE stream, if you need to. (I don't think you need to for PDFs - I think the zLib stream is what you need, as we've discussed.) From this, I also don't think you need to calculate your own adler32 checksum. The result of a zLib compress() call already has one at the end.
    I just read a bit of the spec, initially, I thought it is easy job because there're many open source for this purpose.

    You are right. If we use zLib, there's no necessary add additional such 2 bytes (0x78 and 0x9c) ahead and 4 bytes checksum at end. zLib help us so.

    C# DeflateStream just compress so we must write two bytes in most significant byte first then byte arrays then 4 bytes of CheckSum.

    Sorry for that!

    Edited:
    I removed those 6 bytes, now I finally see the beautiful PDF.
    Thank Tanner. Thank you Sir!

    Edited:
    zLib add two bytes for signature of compress rate:
    COMPRESS_DEFAULT:
    &H78 and &H9C

    COMPRESS_BEST
    120 (&H78) and 218 (&HDA)

    COMPRESS_BESTSPEED:
    zLib Failed

    Some C# code used DeflateStream write &H58 and &H85 or &H78 and &H9C.
    Last edited by Jonney; Sep 17th, 2015 at 01:20 AM.

  30. #30

    Thread Starter
    Frenzied Member
    Join Date
    Jan 2010
    Posts
    1,103

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    Quote Originally Posted by Tanner_H View Post
    Now for your DIB serialization. I think it has some issues. Here is an easier solution. (It might not be perfect because I am writing it on a Mac without testing it, but hopefully you get the idea):

    Code:
    Dim x As Long, y As Long
    
    Dim lineNewArray As Long, lineOldArray as Long
    
    ReDim DIBBits(lImageWidth * lImageHeight * 3 - 1) as Byte
    
    For y = 0 to lImageHeight - 1
    
       lineOldArray = ((lImageHeight - 1) - y) * lImageWidth * 4
       lineNewArray = y * lImageWidth * 3
    
       For x = 0 To lImageWidth - 1
           
           DIBBits(lineNewArray + (x * 3) + 2) = ImageData(lineOldArray + (x * 4))
           DIBBits(lineNewArray + (x * 3) + 1) = ImageData(lineOldArray + (x * 4) + 1)
           DIBBits(lineNewArray + (x * 3)) = ImageData(lineOldArray + (x * 4) + 2)
    
       Next x
    Next y
    Try the result of that serialize approach with a pure zLib stream, and see if it changes anything.
    From What I tested, your re-work is OK. My original one also works.

    Thank you, without you research, I can imagine I am Headless Fly in this week. Highly respect you have great learning capability...In this case, You also start from zero, but you know what you want... Better than me.

  31. #31

    Thread Starter
    Frenzied Member
    Join Date
    Jan 2010
    Posts
    1,103

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    7.4.4LZWDecode and FlateDecode Filters
    7.4.4.1General
    The LZWDecode and (PDF 1.2) FlateDecode filters have much in common and are discussed together in this sub-clause. They decode data that has been encoded using the LZW or Flate data compression method, respectively:
    •LZW (Lempel-Ziv-Welch) is a variable-length, adaptive compression method that has been adopted as one of the standard compression methods in the Tag Image File Format (TIFF) standard. For details on LZW encoding see 7.4.4.2, "Details of LZW Encoding."
    •The Flate method is based on the public-domain zlib/deflate compression method, which is a variable-length Lempel-Ziv adaptive compression method cascaded with adaptive Huffman coding. It is fully defined in Internet RFCs 1950, ZLIB Compressed Data Format Specification, and 1951, DEFLATE Compressed Data Format Specification (see the Bibliography).
    Quote Originally Posted by szlamany View Post
    this section from the PDF spec talks about the compression - is this what you understood it to be?
    Thank you, I should read careful but at that time I was in blame on zLib... zLib works for PDF Stream.

  32. #32
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,253

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    Quote Originally Posted by Jonney View Post
    For junior or intermediate(like me), they have no idea how to use RC5.
    They are afraid of learning new things. They need enough samples, not a document.
    There's quite some examples out there already - and generally nothing "to be afraid of".
    Most classes will behave quite logically, after looking them up in the VB-ObjectExlplorer,
    followed by a short test (many of them are already compatible to known VB6-Objects).

    Quote Originally Posted by Jonney View Post
    Can you please show us how the zLib implement in RC5?
    The following example shows, how you can "cut out" the Raw-Deflate-content over RC5
    (assuming your original DIB-Source-Data comes in as a ByteArray).
    Code:
    Private Sub Form_Load()
    Dim BSrc() As Byte, BDst() As Byte, BRawDeflate() As Byte, Adler32 As Long
        BSrc = "Some DIB Data"
       
      With New_c.Crypt
        .ZlibCompress BSrc, BDst 'compress into BDst, using the ZLib-Deflate-Algo
        Debug.Print "ZLibHdr: 0x"; Hex(BDst(8)); Hex(BDst(9)) 'print out the ZLib-Header as Hex
      End With
     
      With New_c.Stream
        .WriteFromByteArr BDst 'copy the whole content of BDst over into a memory-stream
        .SetPosition 10 'skip the RC5-8Byte-Header + the ZLib-2Byte-Header
        .ReadToByteArr BRawDeflate, .GetSize - (10 + 4) 'read out the Raw-Deflate-Data (without the 4 Adler32-Bytes)
        .ReadToPtr VarPtr(Adler32), 4 'followed by a read-out of the 4 Adler32 Bytes
      End With
      
      Debug.Print "Raw Deflate-Size:"; UBound(BRawDeflate) + 1
      Debug.Print "Adler32-Hex:"; Hex(Adler32)
    End Sub
    The above will print-out:
    Code:
    ZLibHdr: 0x789C
    Raw Deflate-Size: 23 
    Adler32-Hex:1E04003A
    But using the RC5 in this way (just to be able to contribute PDF-content from a "Page-Covering-DIB")
    would be completely unnecessary, since there's direct PDF-Write-support available too,
    e.g. covered in this little example in the CodeBank already:
    http://www.vbforums.com/showthread.p...wingRoutine%29

    So you can render Text-Output - as well as antialiased "Shapes with gradient Fills" - or even "Raw-Bitmaps"
    (in the form of cairo-ImageSurfaces, which will then end up as PNG-content in the generated PDF).

    Olaf

  33. #33

    Thread Starter
    Frenzied Member
    Join Date
    Jan 2010
    Posts
    1,103

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    Quote Originally Posted by Schmidt View Post
    Code:
    ZLibHdr: 0x789C
    Raw Deflate-Size: 23 
    Adler32-Hex:1E04003A
    Olaf
    I just figured out with Tanner help. 0x789C is zLib default compress signature bytes.

    1. How RC5 implement zLib? If my Win7 don't have zLib, what is the RC5 default action?

    2. I don't know why zLib got critical error when we set Compress level to other than default or the Best. Can RC5 set compress level?

  34. #34
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,253

    Re: VB6 Create PDF : RFC 1950 DEFLATE DIBs

    Quote Originally Posted by Jonney View Post
    I just figured out with Tanner help. 0x789C is zLib default compress signature bytes.
    Yep, I've just reported it in the Demo, to make it more clear that the
    "real deflate-stream" will start at Offset 8, when cCrypt.ZLibCompress is used
    (the 8 Bytes of RC5-Header is the FourCharCode for the 4 Chars: "zlib",
    followed by 4Bytes for the size of the "original, uncompressed Input-Source")

    Quote Originally Posted by Jonney View Post
    1. How RC5 implement zLib? If my Win7 don't have zLib, what is the RC5 default action?
    The "default action" is, that it "will work anyways" (because anything the RC5 supports
    over its Class-Wrappers from the "OpenSource-world" - is already statically compiled and
    linked into vb_cairo_sqlite.dll, zlib inclusive ... vb_cairo_sqlite.dll is a __stdcall-compiled, normal Dll).

    Quote Originally Posted by Jonney View Post
    2. I don't know why zLib got critical error when we set Compress level to other than default or the Best.
    Can RC5 set compress level?
    No, currently the cCrypt-Class doesn't support other ZLib-Settings than the default
    in compress-direction - (neither for cCrypt.ZLibCompress, nor for cCrypt.GzCompress).

    Decompression will work with any supported ZLib- or GZip- compression-levels of course.

    I've left this out, because ZLib as a "general purpose compressor" works best in its
    "designed sweet-spot" (a very good compromise between speed and compression-ratio),
    when left at its default-medium-setting.

    If you want to go "faster", then there's cCrypt.FastLZCompress - and if you prefer
    "maximum-compression over speed", then there's cCrypt.LZMAComp/Decomp...
    (both compressors not able to produce streams, understood or accepted by PDF of course)

    But in case of your PDFs, you would achieve (much) smaller PDF-File-Sizes then,
    when you'd say good-bye to your current "FullPage-DIB" per PDF-Page-approach -
    and would use direct PDF-writing instead (this way even being able, to skip your
    current EnhancedMetafile-Rendering as the currently necessary "immediate step").

    Another thing you could try (even when sticking with your Full-Page-DIB-approach), would be
    an attempt, whether the RC5-PDF-Writer (which will use PNG-compression to embed Bitmaps into PDF),
    will produce somewhat smaller PDF-FileSizes in the end.

    Olaf

  35. #35

    Thread Starter
    Frenzied Member
    Join Date
    Jan 2010
    Posts
    1,103

    Re: [RESOLVED] VB6 Create PDF : RFC 1950 DEFLATE DIBs

    But in case of your PDFs, you would achieve (much) smaller PDF-File-Sizes then,
    when you'd say good-bye to your current "FullPage-DIB" per PDF-Page-approach -
    and would use direct PDF-writing instead (this way even being able, to skip your
    current EnhancedMetafile-Rendering as the currently necessary "immediate step").
    OK. I caught your idea.

    If I open the Print preview Form and Choose PDF Creator Printer, the meta file will play into PDF Printer hDC, the PDF Creator save the pdf file size is only 63KB with much very high resolution (600dpi) compare my current Play MFHdl onto A4 Size MemoryDC (96dpi) then "FullPage-DIB" : 140KB (7 Pages all table with text).

    Code:
    PlayEnhMetaFile lhMemoryDC, MFHdl, rc
    I will try direct convert MFHdl to GDI+ hImage (WMF) then save the DIBBits... Any other better direct way?

    (btw: the MFHdl obtained from rendering on default Printer.hDC, so it is 600dpi)
    Last edited by Jonney; Sep 17th, 2015 at 11:43 PM.

  36. #36

    Thread Starter
    Frenzied Member
    Join Date
    Jan 2010
    Posts
    1,103

    Re: [RESOLVED] VB6 Create PDF : RFC 1950 DEFLATE DIBs

    OK. I close this thread since the problem already resolved. I may open a new thread to discuss on Meta File.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width