Updated. Fixed so that it doesn't just stop after screenWindowWidth, but actually stops if the header stops (or larger than 1024).

#############################################

import struct

n = nuke.selectedNode()
filePath = nuke.filename(n, nuke.REPLACE)
file = open(filePath, 'rb')

compressionTypes = ['RAW', 'RLE', 'ZIP1', 'ZIP16', 'PIZ', 'PXR24', 'B44']

compression = 0
if struct.unpack("i4", file.read(4))[0] == 20000630:
    versionFlag = struct.unpack("i4", file.read(4))
    loop = True
    while loop == True:
        i = 0
        size = 0
        headerStart = file.tell()
        headerName = ""
        headerType = ""
        while i <= 50:
            buffer = file.read(1)
            if ord(buffer) == 0 and headerName == "":
                nameSize = file.tell() - headerStart
                file.seek(0-nameSize, 1)
                headerName = file.read(nameSize)[0:-1]
                if len(headerName) == 0:
                    loop = False
                    break
            elif ord(buffer) == 0 and headerType == "":
                nameSize = file.tell() - len(headerName) - 1 - headerStart
                file.seek(0-nameSize, 1)
                headerType = file.read(nameSize)[0:-1]
                headerSize = struct.unpack("i4", file.read(4))[0]
                if headerName == "compression":
                    compression = file.read(1)
                else:
                    file.seek(headerSize, 1)
                break
            if i == 50 or headerStart > 1024:
                loop = False
            i=+1

print(compressionTypes[ord(compression)])


#############################################

Best Regards
Jimmy Christensen
Developer
Ghost A/S


On 24/05/12 16:06, Jimmy Christensen wrote:
I also wanted to pitch in :)

It parses the file instead of just searching. Can be extended to check
for other stuff. Stops after the first 1024 bytes and after hitting the
"screenWindowWidth" header.

#############################################

import struct

n = nuke.selectedNode()
filePath = nuke.filename(n, nuke.REPLACE)
file = open(filePath, 'rb')

compressionTypes = ['RAW', 'RLE', 'ZIP1', 'ZIP16', 'PIZ', 'PXR24', 'B44']

#test = file.read(4)
compression = 0
if struct.unpack("i4", file.read(4))[0] == 20000630:
     versionFlag = struct.unpack("i4", file.read(4))
     loop = True
     while loop == True:
         i = 0
         size = 0
         headerStart = file.tell()
         headerName = ""
         headerType = ""
         while i <= 50:
             buffer = file.read(1)
             if ord(buffer) == 0 and headerName == "":
                 nameSize = file.tell() - headerStart
                 file.seek(0-nameSize, 1)
                 headerName = file.read(nameSize)[0:-1]
             elif ord(buffer) == 0 and headerType == "":
                 nameSize = file.tell() - len(headerName) - 1 - headerStart
                 file.seek(0-nameSize, 1)
                 headerType = file.read(nameSize)[0:-1]
                 headerSize = struct.unpack("i4", file.read(4))[0]
                 if headerName == "compression":
                     compression = file.read(1)
                 else:
                     file.seek(headerSize, 1)
                 if headerName == "screenWindowWidth":
                     loop = False
                 break
             if i == 50 or headerStart > 1024:
                 loop = False
             i=+1

print(compressionTypes[ord(compression)])

#############################################

Best Regards
Jimmy Christensen
Developer
Ghost A/S


On 23/05/12 01:28, Adrian Baltowski wrote:
Hi

In fact each channel name in exr can be 31 bytes long, so even 4096
could be too less in some extreme cases. On the other side we don't
want to read too much.
The code below fix this issue: I did small modifications to read
actual size of channels list and skip over, no matter how many
channels is in the file. I added few comments to clarify.


########################
import struct

compList = ['None', 'RLE', 'ZIP', 'ZIP 16 lines', 'PIZ', 'PXR24',
'B44', 'B44A']

n = nuke.selectedNode()
file = nuke.filename(n, nuke.REPLACE)
fd = open(file, 'rb')
# read small portion of data
header = fd.read(256)

# search for channels list tag. Well... in fact we could hardcode this
position but I prefer to write it more flexible
channels = header.find('channels')

# skip the tags...
fd.seek(channels+16)

# ...and read the actual size of channels list. We know, that it's
4-byte integer
channelsSize = fd.read(4)

# Ok, so we know how long (in bytes) is the channels list in our file.
And we simply jump over
fd.seek(struct.unpack('i', channelsSize)[0], 1)

# Here we are
position = fd.tell()

# read next portion of data and search for compression
header = fd.read(256)
index = header.find('compression')
fd.seek(position + index+28)
comp = ord(fd.read(1))
print compList[comp]


######################################



Best
Adrian




Nathan,

Thanks for the PDF link to the OpenEXR file layout - I was looking
for something like that!

Rich

On May 22, 2012, at 1:23 PM, Nathan Rusch wrote:

The compression attribute will be in a different place within the
header depending on the number of channels in the file (due to the
layout of the EXR header).

Adrian's snippet is simply finding the 'compression' attribute name
within the header, since that is one of the standard EXR attributes.
From there, based on known information about the EXR file layout, he
can determine where the actual compression attribute value is stored.

The read size of 1024 is pretty much an arbitrary value; you may
need to read a larger chunk in order to get far enough into the file
to locate the compression attribute if your file has a lot of
channels. If you know the names of all the channels within the file,
you could figure out exactly how many bytes to read, or even start
your read from a predefined offset to keep your data buffer as small
as possible; otherwise, you'll just need to make a safe estimate.

Check out this doc for a nice simple example of the structure of an
EXR file: http://www.openexr.com/openexrfilelayout.pdf

Hope this helps.

-Nathan


-----Original Message----- From: Dan Rosen
Sent: Tuesday, May 22, 2012 9:59 AM
To: Nuke user discussion
Subject: Re: [Nuke-users] How to check zip compression type for EXR
images...?

This is great! Can you let us know what index number the datatype is
in? I'm finding it hard to tell.

thx
Dan

On Mon, May 21, 2012 at 7:30 PM, Richard Bobo <[email protected]> wrote:
Adrian,

Brilliant - I'll be making it into a nice little pulldown menu utility
function! And, looking a bit deeper at your code, of course, so I
can learn
some more Python...  8^)

Thanks!

Rich

Rich Bobo
Senior VFX Compositor

Mobile:  (248) 840-2665
Web:  http://richbobo.com/

"Man has been endowed with reason, with the power to create, so
that he can
add to what he's been given."
- Anton Chekhov



On May 21, 2012, at 6:40 PM, Adrian Baltowski wrote:

Hi
With just few lines of code and totally simplified

**********************************
compList = ['None', 'RLE', 'ZIP', 'ZIP 16 lines', 'PIZ', 'PXR24',
'B44',
'B44A']

n = nuke.selectedNode()
file = nuke.filename(n, nuke.REPLACE)
fd = open(file, 'rb')
header = fd.read(1024)
index = header.find('compression')
comp =ord(header[(index+28):(index+29)])
print compList[comp]

***********************************

Each exr file MUST have compression info in the header and this
info is
placed just after channels info. It's simple to get actual size of
channels
list but I quickly set 1024 bytes of a headroom.

Best
Adrian

_______________________________________________
Nuke-users mailing list
[email protected], http://forums.thefoundry.co.uk/
http://support.thefoundry.co.uk/cgi-bin/mailman/listinfo/nuke-users

_______________________________________________
Nuke-users mailing list
[email protected], http://forums.thefoundry.co.uk/
http://support.thefoundry.co.uk/cgi-bin/mailman/listinfo/nuke-users


_______________________________________________
Nuke-users mailing list
[email protected], http://forums.thefoundry.co.uk/
http://support.thefoundry.co.uk/cgi-bin/mailman/listinfo/nuke-users


_______________________________________________
Nuke-users mailing list
[email protected], http://forums.thefoundry.co.uk/
http://support.thefoundry.co.uk/cgi-bin/mailman/listinfo/nuke-users

_______________________________________________
Nuke-users mailing list
[email protected], http://forums.thefoundry.co.uk/
http://support.thefoundry.co.uk/cgi-bin/mailman/listinfo/nuke-users

Reply via email to