Mini Shell

Direktori : /opt/imh-python/lib/python2.7/site-packages/construct/formats/graphics/
Upload File :
Current File : //opt/imh-python/lib/python2.7/site-packages/construct/formats/graphics/png.py

"""
Portable Network Graphics (PNG) file format
Official spec: http://www.w3.org/TR/PNG

Original code contributed by Robin Munn (rmunn at pobox dot com)
(although the code has been extensively reorganized to meet Construct's
coding conventions)
"""
from construct import *
import six


#===============================================================================
# utils
#===============================================================================
def Coord(name, field=UBInt8):
    return Struct(name,
        field("x"),
        field("y"),
    )

compression_method = Enum(UBInt8("compression_method"),
    deflate = 0,
    _default_ = Pass
)


#===============================================================================
# 11.2.3: PLTE - Palette
#===============================================================================
plte_info = Struct("plte_info",
    Value("num_entries", lambda ctx: ctx._.length / 3),
    Array(lambda ctx: ctx.num_entries,
        Struct("palette_entries",
            UBInt8("red"),
            UBInt8("green"),
            UBInt8("blue"),
        ),
    ),
)

#===============================================================================
# 11.2.4: IDAT - Image data
#===============================================================================
idat_info = OnDemand(
    Field("idat_info", lambda ctx: ctx.length),
)

#===============================================================================
# 11.3.2.1: tRNS - Transparency
#===============================================================================
trns_info = Switch("trns_info", lambda ctx: ctx._.image_header.color_type, 
    {
        "greyscale": Struct("data",
            UBInt16("grey_sample")
        ),
        "truecolor": Struct("data",
            UBInt16("red_sample"),
            UBInt16("blue_sample"),
            UBInt16("green_sample"),
        ),
        "indexed": Array(lambda ctx: ctx.length,
            UBInt8("alpha"),
        ),
    }
)

#===============================================================================
# 11.3.3.1: cHRM - Primary chromacities and white point
#===============================================================================
chrm_info = Struct("chrm_info",
    Coord("white_point", UBInt32),
    Coord("red", UBInt32),
    Coord("green", UBInt32),
    Coord("blue", UBInt32),
)

#===============================================================================
# 11.3.3.2: gAMA - Image gamma
#===============================================================================
gama_info = Struct("gama_info",
    UBInt32("gamma"),
)

#===============================================================================
# 11.3.3.3: iCCP - Embedded ICC profile
#===============================================================================
iccp_info = Struct("iccp_info",
    CString("name"),
    compression_method,
    Field("compressed_profile", 
        lambda ctx: ctx._.length - (len(ctx.name) + 2)
    ),
)

#===============================================================================
# 11.3.3.4: sBIT - Significant bits
#===============================================================================
sbit_info = Switch("sbit_info", lambda ctx: ctx._.image_header.color_type, 
    {
        "greyscale": Struct("data",
            UBInt8("significant_grey_bits"),
        ),
        "truecolor": Struct("data",
            UBInt8("significant_red_bits"),
            UBInt8("significant_green_bits"),
            UBInt8("significant_blue_bits"),
        ),
        "indexed": Struct("data",
            UBInt8("significant_red_bits"),
            UBInt8("significant_green_bits"),
            UBInt8("significant_blue_bits"),
        ),
        "greywithalpha": Struct("data",
            UBInt8("significant_grey_bits"),
            UBInt8("significant_alpha_bits"),
        ),
        "truewithalpha": Struct("data",
            UBInt8("significant_red_bits"),
            UBInt8("significant_green_bits"),
            UBInt8("significant_blue_bits"),
            UBInt8("significant_alpha_bits"),
        ),
    }
)

#===============================================================================
# 11.3.3.5: sRGB - Standard RPG color space
#===============================================================================
srgb_info = Struct("srgb_info",
    Enum(UBInt8("rendering_intent"),
        perceptual = 0,
        relative_colorimetric = 1,
        saturation = 2,
        absolute_colorimetric = 3,
        _default_ = Pass,
    ),
)

#===============================================================================
# 11.3.4.3: tEXt - Textual data
#===============================================================================
text_info = Struct("text_info",
    CString("keyword"),
    Field("text", lambda ctx: ctx._.length - (len(ctx.keyword) + 1)),
)

#===============================================================================
# 11.3.4.4: zTXt - Compressed textual data
#===============================================================================
ztxt_info = Struct("ztxt_info",
    CString("keyword"),
    compression_method,
    OnDemand(
        Field("compressed_text",
            # As with iCCP, length is chunk length, minus length of
            # keyword, minus two: one byte for the null terminator,
            # and one byte for the compression method.
            lambda ctx: ctx._.length - (len(ctx.keyword) + 2),
        ),
    ),
)

#===============================================================================
# 11.3.4.5: iTXt - International textual data
#===============================================================================
itxt_info = Struct("itxt_info",
    CString("keyword"),
    UBInt8("compression_flag"),
    compression_method,
    CString("language_tag"),
    CString("translated_keyword"),
    OnDemand(
        Field("text",
            lambda ctx: ctx._.length - (len(ctx.keyword) + 
            len(ctx.language_tag) + len(ctx.translated_keyword) + 5),
        ),
    ),
)

#===============================================================================
# 11.3.5.1: bKGD - Background color
#===============================================================================
bkgd_info = Switch("bkgd_info", lambda ctx: ctx._.image_header.color_type, 
    {
        "greyscale": Struct("data",
            UBInt16("background_greyscale_value"),
            Alias("grey", "background_greyscale_value"),
        ),
        "greywithalpha": Struct("data",
            UBInt16("background_greyscale_value"),
            Alias("grey", "background_greyscale_value"),
        ),
        "truecolor": Struct("data",
            UBInt16("background_red_value"),
            UBInt16("background_green_value"),
            UBInt16("background_blue_value"),
            Alias("red", "background_red_value"),
            Alias("green", "background_green_value"),
            Alias("blue", "background_blue_value"),
        ),
        "truewithalpha": Struct("data",
            UBInt16("background_red_value"),
            UBInt16("background_green_value"),
            UBInt16("background_blue_value"),
            Alias("red", "background_red_value"),
            Alias("green", "background_green_value"),
            Alias("blue", "background_blue_value"),
        ),
        "indexed": Struct("data",
            UBInt16("background_palette_index"),
            Alias("index", "background_palette_index"),
        ),
    }
)

#===============================================================================
# 11.3.5.2: hIST - Image histogram
#===============================================================================
hist_info = Array(lambda ctx: ctx._.length / 2,
    UBInt16("frequency"),
)

#===============================================================================
# 11.3.5.3: pHYs - Physical pixel dimensions
#===============================================================================
phys_info = Struct("phys_info",
    UBInt32("pixels_per_unit_x"),
    UBInt32("pixels_per_unit_y"),
    Enum(UBInt8("unit"),
        unknown = 0,
        meter = 1,
        _default_ = Pass
    ),
)

#===============================================================================
# 11.3.5.4: sPLT - Suggested palette
#===============================================================================
def splt_info_data_length(ctx):
    if ctx.sample_depth == 8:
        entry_size = 6
    else:
        entry_size = 10
    return (ctx._.length - len(ctx.name) - 2) / entry_size

splt_info = Struct("data",
    CString("name"),
    UBInt8("sample_depth"),
    Array(lambda ctx: splt_info_data_length,
        IfThenElse("table", lambda ctx: ctx.sample_depth == 8,
            # Sample depth 8
            Struct("table",
                UBInt8("red"),
                UBInt8("green"),
                UBInt8("blue"),
                UBInt8("alpha"),
                UBInt16("frequency"),
            ),
            # Sample depth 16
            Struct("table",
                UBInt16("red"),
                UBInt16("green"),
                UBInt16("blue"),
                UBInt16("alpha"),
                UBInt16("frequency"),
            ),
        ),
    ),
)

#===============================================================================
# 11.3.6.1: tIME - Image last-modification time
#===============================================================================
time_info = Struct("data",
    UBInt16("year"),
    UBInt8("month"),
    UBInt8("day"),
    UBInt8("hour"),
    UBInt8("minute"),
    UBInt8("second"),
)

#===============================================================================
# chunks
#===============================================================================
default_chunk_info = OnDemand(
    HexDumpAdapter(Field(None, lambda ctx: ctx.length))
)

chunk = Struct("chunk",
    UBInt32("length"),
    String("type", 4),
    Switch("data", lambda ctx: ctx.type, 
        {
            "PLTE" : plte_info,
            "IEND" : Pass,
            "IDAT" : idat_info,
            "tRNS" : trns_info,
            "cHRM" : chrm_info,
            "gAMA" : gama_info,
            "iCCP" : iccp_info,
            "sBIT" : sbit_info,
            "sRGB" : srgb_info,
            "tEXt" : text_info,
            "zTXt" : ztxt_info,
            "iTXt" : itxt_info,
            "bKGD" : bkgd_info,
            "hIST" : hist_info,
            "pHYs" : phys_info,
            "sPLT" : splt_info,
            "tIME" : time_info,
        },
        default = default_chunk_info,
    ),
    UBInt32("crc"),
)

image_header_chunk = Struct("image_header",
    UBInt32("length"),
    Const(String("type", 4), "IHDR"),
    UBInt32("width"),
    UBInt32("height"),
    UBInt8("bit_depth"),
    Enum(UBInt8("color_type"),
        greyscale = 0,
        truecolor = 2,
        indexed = 3,
        greywithalpha = 4,
        truewithalpha = 6,
        _default_ = Pass,
    ),
    compression_method,
    Enum(UBInt8("filter_method"),
        # "adaptive filtering with five basic filter types"
        adaptive5 = 0,
        _default_ = Pass,
    ),
    Enum(UBInt8("interlace_method"),
        none = 0,
        adam7 = 1,
        _default_ = Pass,
    ),
    UBInt32("crc"),
)


#===============================================================================
# the complete PNG file
#===============================================================================
png_file = Struct("png",
    Magic(six.b("\x89PNG\r\n\x1a\n")),
    image_header_chunk,
    Rename("chunks", GreedyRange(chunk)),
)

Zerion Mini Shell 1.0