summaryrefslogtreecommitdiff
path: root/external/construct/formats/graphics/png.py
diff options
context:
space:
mode:
authorLivio Recchia <recchialivio@libero.it>2020-02-10 23:06:34 +0100
committerLivio Recchia <recchialivio@libero.it>2020-02-10 23:06:34 +0100
commit9a13903a2f7d3a65fdf15a65fb59cccd622e2066 (patch)
tree9403b7dff39eb5e5d7fa0f79efb69b496add4c4b /external/construct/formats/graphics/png.py
parent11cc316b74d5f3f283413a33e7693b314741aa4a (diff)
downloadmanachat-9a13903a2f7d3a65fdf15a65fb59cccd622e2066.tar.gz
manachat-9a13903a2f7d3a65fdf15a65fb59cccd622e2066.tar.bz2
manachat-9a13903a2f7d3a65fdf15a65fb59cccd622e2066.tar.xz
manachat-9a13903a2f7d3a65fdf15a65fb59cccd622e2066.zip
Initial commit
Diffstat (limited to 'external/construct/formats/graphics/png.py')
-rw-r--r--external/construct/formats/graphics/png.py355
1 files changed, 355 insertions, 0 deletions
diff --git a/external/construct/formats/graphics/png.py b/external/construct/formats/graphics/png.py
new file mode 100644
index 0000000..39edf3a
--- /dev/null
+++ b/external/construct/formats/graphics/png.py
@@ -0,0 +1,355 @@
+"""
+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)),
+)