Results 1 to 11 of 11

Thread: [RESOLVED] 48-bit tiff

  1. #1

    Thread Starter
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Resolved [RESOLVED] 48-bit tiff

    Anyone out there has code to read a 48 bit (16 bits per colour channel) tiff file?
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

  2. #2
    Cumbrian Milk's Avatar
    Join Date
    Jan 2007
    Location
    0xDEADBEEF
    Posts
    2,448

    Re: 48-bit tiff

    As far as I understand a Tiff is not really an image format itself rather a way of containing one or more files of different formats as one file. The image contained could be a Ping, Jpeg, Bitmap or raw data (a bitmap without a header).

    If this image is in Jpeg2000 format then I don't know how to extract it from the Tiff. If it's in a raw or bitmap format it should be fairly straight forward, assuming it's a RGB format rather than a CYMK (printer) format. Once the pixel data has been found it's a case of copying every other byte (the hi order byte) to a new image. A 48bit image cannot be displayed without losing information.

    How huge are the files in question? I think you still have my email, if you do you could send it to me and I'll be better placed to tell you how to extract the image.
    Last edited by Milk; Aug 28th, 2008 at 04:52 AM.

  3. #3

    Thread Starter
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: 48-bit tiff

    Quote Originally Posted by Milk
    As far as I understand a Tiff is not really an image format itself rather a way of containing one or more files of different formats as one file. The image contained could be a Ping, Jpeg, Bitmap or raw data (a bitmap without a header).
    Well, I have no idea about its structure.
    Quote Originally Posted by Milk
    If this image is in Jpeg2000 format then I don't know how to extract it from the Tiff. If it's in a raw or bitmap format it should be fairly straight forward, assuming it's a RGB format rather than a CYMK (printer) format. Once the pixel data has been found it's a case of copying every other byte (the hi order byte) to a new image. A 48bit image cannot be displayed without losing information.
    Actually I want to separate the 3 channels, R G & B and plot one of them as grayscale.
    Quote Originally Posted by Milk
    How huge are the files in question? I think you still have my email, if you do you could send it to me and I'll be better placed to tell you how to extract the image.
    Just about 2 or 3 Mb. But I've cropped an image which is now about 100 kb to e-mail it to you.
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

  4. #4
    Cumbrian Milk's Avatar
    Join Date
    Jan 2007
    Location
    0xDEADBEEF
    Posts
    2,448

    Re: 48-bit tiff

    Cheers for that...
    Right it's a Big Endian tiff which is a pain to read with VB which likes Little Endian numbers. The program I have written is not yet capable of reading Big Endian Tiffs but this is something I've been meaning to address for some time, this sounds like just the excuse I need. In the meantime there might be some some Tiff parser you can find at PSC or somesuch that will do the job.

    The size of the file compared to the size of the image within does suggest that it's stored in a raw or Bitmap format of 6 bytes per pixel, making it easy to extract once the Tiff directories can be navigated.

    The information that is needed are the image dimensions and the offset of the pixel data.

  5. #5

    Thread Starter
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: 48-bit tiff

    Quote Originally Posted by Milk
    ...In the meantime there might be some some Tiff parser you can find at PSC or somesuch that will do the job.
    Well, I'm using a third party program, ImageJ ( http://rsbweb.nih.gov/ij/ ) which allows me to load the tiff and then save it as an array of tab separated text values, which is easy to handle with vb. But I want to skip this step and that's why I'd like to handle the tiff with vb.
    Quote Originally Posted by Milk
    ...
    The information that is needed are the image dimensions and the offset of the pixel data.
    Image size is 181 x 106 pixels. I'm going to e-mail you the ImageJ converted file.
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

  6. #6

    Thread Starter
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: 48-bit tiff

    Forgot to mention: in case it's any use to you, in the ImageJ web site the Java source code -including the tiff decoding part- is available, but I don't know Java.
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

  7. #7
    Cumbrian Milk's Avatar
    Join Date
    Jan 2007
    Location
    0xDEADBEEF
    Posts
    2,448

    Re: 48-bit tiff

    ***An email exchange later***

    Attached is a class that can parse Tiffs, here is an example of some code to extract the byte data.
    vb Code:
    1. Option Explicit
    2.  
    3. Private Sub Form_Load()
    4. Dim Tiff As cTiffInfo, Pix() As Byte
    5. Dim Wdth As Long, Hght As Long
    6. Dim IsBigEndian As Boolean
    7. Dim i As Long
    8.  
    9.    Set Tiff = New cTiffInfo
    10.    With Tiff
    11.       .OpenTiff App.Path & "/euro 600 dpi.tif" 'this locks the file until CloseTiff or class terminate
    12.       Wdth = .ReadTag(ImageWidth) '<-- Endianess is converted for all tag data
    13.       Hght = .ReadTag(ImageLength) 'TIFFs support many datatypes that VB6 does not, beware of signage.
    14.       Pix = .PixelData '<-- Endianess is NOT converted for pixel data
    15.       If UBound(Pix) + 1 = Wdth * Hght * 6 Then 'Is it 48-Bit per pixel, Good enough for this....
    16.       '(TIFF in theory can use a different number bits for each channel)
    17.          Call My48BitImageFunction(Pix, Wdth, .IsBigEndian)
    18.       Else
    19.          Debug.Print "Not a 48bit image"
    20.       End If
    21.    End With
    22.    Set Tiff = Nothing 'not required, just a good habit
    23. End Sub
    The function that receives the 48bit (6 byte/pixel) byte data must choose one of the three high order bytes for the greyscale image. The High order bytes will be the odd indexes for Little-Endian data (even for Big-En...) . It is possible with DibSection Api to work with GreyScale Bitmaps, copy the right bytes to one of those and you're laughing.

    I think that Java code you have converts to BigEndian, the scanner TIFFs you sent are Intel friendly.

    Good Luck
    Attached Files Attached Files
    Last edited by Milk; Aug 29th, 2008 at 05:14 PM.

  8. #8

    Thread Starter
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: 48-bit tiff

    This looks incredible let me just take a deep breath and start playing around with it.
    Quote Originally Posted by Milk
    ...
    I think that Java code you have converts to BigEndian, the scanner TIFFs you sent are Intel friendly...
    Maybe this ImageJ thing was first developed for Unix, I once wrote code for parsing files ftp'd from a Unix system and I seem to recall they were big endian.
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

  9. #9

    Thread Starter
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: [RESOLVED] 48-bit tiff

    I'm really happy with your code. For now I've just managed to extract the channels,
    VB Code:
    1. Dim redch() As Long, greench() As Long, bluech() As Long
    2. Private Sub ExtractChannels(pix, redch, greench, bluech)
    3.     Dim pch As Long, i As Long, j As Long
    4.    
    5.     pch = (1 + UBound(pix)) \ 6 - 1
    6.     ReDim redch(pch), greench(pch), bluech(pch)
    7.     For i = 0 To pch
    8.         j = 6 * i
    9.         redch(i) = 256 * pix(j + 1) + pix(j)
    10.         greench(i) = 256 * pix(j + 3) + pix(j + 2)
    11.         bluech(i) = 256 * pix(j + 5) + pix(j + 4)
    12.     Next
    13. End Sub
    I assume you have to switch the bytes for big endian, for example,

    redch(i) = 256 * pix(j) + pix(j + 1)

    Edit: this is only because I want to keep the full information per channel that I need for some further processing. Thereafter, when it comes to plot the image then I can keep only the high order byte, odd for little endian as you've pointed out.
    Last edited by krtxmrtz; Aug 31st, 2008 at 10:56 AM.
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

  10. #10

    Thread Starter
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: 48-bit tiff

    ...and I've created the bitmap from the high order bytes.

    VB Code:
    1. Private Sub Create2DBitmap(pix, wd, ht, bm)
    2.     Dim i As Long, j As Long
    3.     Dim row As Integer, col As Integer
    4.     Dim nPx As Long
    5.    
    6.     ReDim bm(wd - 1, ht - 1) 'The 2D bitmap to be filled
    7.     nPx = (1 + UBound(pix)) \ 6 - 1 'Total number of pixels
    8.     For i = 0 To nPx
    9.         j = 6 * i + 1
    10.         row = (nPx - i) \ wd 'The rows must start at the
    11.         'bottom or else the image will be inverted
    12.         col = wd - 1 - (nPx - i - row * wd)
    13.         bm(col, row) = RGB(pix(j + 4), pix(j + 2), pix(j))
    14.     Next
    15. End Sub
    and now it can be called for plotting from within your code above:
    VB Code:
    1. '...
    2.       Dim mybm() As Long  
    3.       '...
    4.       If UBound(Pix) + 1 = Wdth * Hght * 6
    5.             Call Create2DBitmap(pix, Wdth, Hght, mybm)
    6.             Picture1.Width = Wdth + 2 * bWdt 'Account for
    7.             'the border width of the picturebox
    8.             Picture1.Height = Hght + 2 * bWdt
    9.             Call DrawData(Picture1.hdc, mybm)
    10.       Else
    11.          Debug.Print "Not a 48bit image"
    12.       End If
    13.       '...
    where DrawData is the function you sent me some time ago based on SetDIBitsToDevice.
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

  11. #11

    Thread Starter
    vbuggy krtxmrtz's Avatar
    Join Date
    May 2002
    Location
    In a probability cloud
    Posts
    5,573

    Re: [RESOLVED] 48-bit tiff

    I thought it might be useful to transcribe here your DrawData function:
    VB Code:
    1. '(In a module)
    2. Option Explicit
    3. Private Type RGBQUAD
    4.     blue As Byte
    5.     green As Byte
    6.     red As Byte
    7.     alpha As Byte
    8. End Type
    9.  
    10. Private Type BITMAPINFOHEADER
    11.     bmSize As Long
    12.     bmWidth As Long
    13.     bmHeight As Long
    14.     bmPlanes As Integer
    15.     bmBitCount As Integer
    16.     bmCompression As Long
    17.     bmSizeImage As Long
    18.     bmXPelsPerMeter As Long
    19.     bmYPelsPerMeter As Long
    20.     bmClrUsed As Long
    21.     bmClrImportant As Long
    22. End Type
    23.  
    24. Private Type BITMAPINFO
    25.     bmHeader As BITMAPINFOHEADER
    26.     bmColors(0 To 255) As RGBQUAD
    27. End Type
    28.  
    29. Private Declare Function SetDIBitsToDevice Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, _
    30. ByVal y As Long, ByVal dx As Long, ByVal dy As Long, ByVal SrcX As Long, ByVal SrcY As Long, _
    31. ByVal Scan As Long, ByVal NumScans As Long, Bits As Any, BitsInfo As BITMAPINFO, _
    32. ByVal wUsage As Long) As Long
    33.  
    34. Public Declare Function StretchBlt Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal XSrc As Long, ByVal YSrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long
    35. Public Declare Function SetStretchBltMode Lib "gdi32" (ByVal hdc As Long, ByVal hStretchMode As Long) As Long
    36. Public Const STRETCHMODE = vbPaletteModeNone
    37.  
    38. Public Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal XSrc As Long, ByVal YSrc As Long, ByVal dwRop As Long) As Long
    39. Public Const SRCCOPY = &HCC0020
    40. '...
    41. '...
    42. Public Sub DrawData(handledc As Long, lngImageData2D() As Long)
    43.     Dim bmi As BITMAPINFO
    44.    
    45.     With bmi.bmHeader
    46.         .bmBitCount = 32
    47.         .bmPlanes = 1
    48.         .bmSize = Len(bmi.bmHeader)
    49.         .bmWidth = UBound(lngImageData2D, 1) + 1
    50.         .bmHeight = UBound(lngImageData2D, 2) + 1
    51.         SetDIBitsToDevice handledc, 0, 0, .bmWidth, .bmHeight, 0, 0, 0, .bmHeight, lngImageData2D(0, 0), bmi, 0
    52.     End With
    53.    
    54. End Sub
    Lottery is a tax on people who are bad at maths
    If only mosquitoes sucked fat instead of blood...
    To do is to be (Descartes). To be is to do (Sartre). To be do be do (Sinatra)

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