mirror of
https://github.com/googlefonts/noto-emoji.git
synced 2025-06-08 07:47:59 +00:00
commit
018aa149d6
21 changed files with 78 additions and 57 deletions
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
waveflag
|
||||||
|
build/
|
9
Makefile
9
Makefile
|
@ -19,6 +19,7 @@ CFLAGS = -std=c99 -Wall -Wextra `pkg-config --cflags --libs cairo`
|
||||||
LDFLAGS = -lm `pkg-config --libs cairo`
|
LDFLAGS = -lm `pkg-config --libs cairo`
|
||||||
|
|
||||||
PNGQUANT = pngquant
|
PNGQUANT = pngquant
|
||||||
|
PYTHON = python3
|
||||||
PNGQUANTFLAGS = --speed 1 --skip-if-larger --quality 85-95 --force
|
PNGQUANTFLAGS = --speed 1 --skip-if-larger --quality 85-95 --force
|
||||||
BODY_DIMENSIONS = 136x128
|
BODY_DIMENSIONS = 136x128
|
||||||
IMOPS := -size $(BODY_DIMENSIONS) canvas:none -compose copy -gravity center
|
IMOPS := -size $(BODY_DIMENSIONS) canvas:none -compose copy -gravity center
|
||||||
|
@ -88,7 +89,7 @@ FLAG_NAMES = $(FLAGS:%=%.png)
|
||||||
FLAG_FILES = $(addprefix $(FLAGS_DIR)/, $(FLAG_NAMES))
|
FLAG_FILES = $(addprefix $(FLAGS_DIR)/, $(FLAG_NAMES))
|
||||||
RESIZED_FLAG_FILES = $(addprefix $(RESIZED_FLAGS_DIR)/, $(FLAG_NAMES))
|
RESIZED_FLAG_FILES = $(addprefix $(RESIZED_FLAGS_DIR)/, $(FLAG_NAMES))
|
||||||
|
|
||||||
FLAG_GLYPH_NAMES = $(shell ./flag_glyph_name.py $(FLAGS))
|
FLAG_GLYPH_NAMES = $(shell $(PYTHON) flag_glyph_name.py $(FLAGS))
|
||||||
RENAMED_FLAG_NAMES = $(FLAG_GLYPH_NAMES:%=emoji_%.png)
|
RENAMED_FLAG_NAMES = $(FLAG_GLYPH_NAMES:%=emoji_%.png)
|
||||||
RENAMED_FLAG_FILES = $(addprefix $(RENAMED_FLAGS_DIR)/, $(RENAMED_FLAG_NAMES))
|
RENAMED_FLAG_FILES = $(addprefix $(RENAMED_FLAGS_DIR)/, $(RENAMED_FLAG_NAMES))
|
||||||
|
|
||||||
|
@ -207,7 +208,7 @@ endif
|
||||||
# Run make without -j if this happens.
|
# Run make without -j if this happens.
|
||||||
|
|
||||||
%.ttx: %.ttx.tmpl $(ADD_GLYPHS) $(ALL_COMPRESSED_FILES)
|
%.ttx: %.ttx.tmpl $(ADD_GLYPHS) $(ALL_COMPRESSED_FILES)
|
||||||
@python $(ADD_GLYPHS) -f "$<" -o "$@" -d "$(COMPRESSED_DIR)" $(ADD_GLYPHS_FLAGS)
|
@$(PYTHON) $(ADD_GLYPHS) -f "$<" -o "$@" -d "$(COMPRESSED_DIR)" $(ADD_GLYPHS_FLAGS)
|
||||||
|
|
||||||
%.ttf: %.ttx
|
%.ttf: %.ttx
|
||||||
@rm -f "$@"
|
@rm -f "$@"
|
||||||
|
@ -215,8 +216,8 @@ endif
|
||||||
|
|
||||||
$(EMOJI).ttf: $(EMOJI).tmpl.ttf $(EMOJI_BUILDER) $(PUA_ADDER) \
|
$(EMOJI).ttf: $(EMOJI).tmpl.ttf $(EMOJI_BUILDER) $(PUA_ADDER) \
|
||||||
$(ALL_COMPRESSED_FILES) | check_vs_adder
|
$(ALL_COMPRESSED_FILES) | check_vs_adder
|
||||||
@python $(EMOJI_BUILDER) $(SMALL_METRICS) -V $< "$@" "$(COMPRESSED_DIR)/emoji_u"
|
@$(PYTHON) $(EMOJI_BUILDER) $(SMALL_METRICS) -V $< "$@" "$(COMPRESSED_DIR)/emoji_u"
|
||||||
@python $(PUA_ADDER) "$@" "$@-with-pua"
|
@$(PYTHON) $(PUA_ADDER) "$@" "$@-with-pua"
|
||||||
@$(VS_ADDER) -vs 2640 2642 2695 --dstdir '.' -o "$@-with-pua-varsel" "$@-with-pua"
|
@$(VS_ADDER) -vs 2640 2642 2695 --dstdir '.' -o "$@-with-pua-varsel" "$@-with-pua"
|
||||||
@mv "$@-with-pua-varsel" "$@"
|
@mv "$@-with-pua-varsel" "$@"
|
||||||
@rm "$@-with-pua"
|
@rm "$@-with-pua"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python3
|
||||||
#
|
#
|
||||||
# Copyright 2017 Google Inc. All rights reserved.
|
# Copyright 2017 Google Inc. All rights reserved.
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python3
|
||||||
#
|
#
|
||||||
# Copyright 2014 Google Inc. All rights reserved.
|
# Copyright 2014 Google Inc. All rights reserved.
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
"""Extend a ttx file with additional data.
|
"""Extend a ttx file with additional data.
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ def collect_seq_to_file(image_dirs, prefix, suffix):
|
||||||
|
|
||||||
|
|
||||||
def remap_values(seq_to_file, map_fn):
|
def remap_values(seq_to_file, map_fn):
|
||||||
return {k: map_fn(v) for k, v in seq_to_file.iteritems()}
|
return {k: map_fn(v) for k, v in seq_to_file.items()}
|
||||||
|
|
||||||
|
|
||||||
def get_png_file_to_advance_mapper(lineheight):
|
def get_png_file_to_advance_mapper(lineheight):
|
||||||
|
@ -280,7 +280,7 @@ def add_ligature_sequences(font, seqs, aliases):
|
||||||
return
|
return
|
||||||
|
|
||||||
rtl_seq_to_target_name = {
|
rtl_seq_to_target_name = {
|
||||||
get_rtl_seq(seq): name for seq, name in seq_to_target_name.iteritems()}
|
get_rtl_seq(seq): name for seq, name in seq_to_target_name.items()}
|
||||||
seq_to_target_name.update(rtl_seq_to_target_name)
|
seq_to_target_name.update(rtl_seq_to_target_name)
|
||||||
# sequences that don't have rtl variants get mapped to the empty sequence,
|
# sequences that don't have rtl variants get mapped to the empty sequence,
|
||||||
# delete it.
|
# delete it.
|
||||||
|
@ -289,7 +289,7 @@ def add_ligature_sequences(font, seqs, aliases):
|
||||||
|
|
||||||
# organize by first codepoint in sequence
|
# organize by first codepoint in sequence
|
||||||
keyed_ligatures = collections.defaultdict(list)
|
keyed_ligatures = collections.defaultdict(list)
|
||||||
for t in seq_to_target_name.iteritems():
|
for t in seq_to_target_name.items():
|
||||||
first_cp = t[0][0]
|
first_cp = t[0][0]
|
||||||
keyed_ligatures[first_cp].append(t)
|
keyed_ligatures[first_cp].append(t)
|
||||||
|
|
||||||
|
@ -339,7 +339,7 @@ def apply_aliases(seq_dict, aliases):
|
||||||
source is a key in the dictionary, we can delete it. This updates the
|
source is a key in the dictionary, we can delete it. This updates the
|
||||||
dictionary and returns the usable aliases."""
|
dictionary and returns the usable aliases."""
|
||||||
usable_aliases = {}
|
usable_aliases = {}
|
||||||
for k, v in aliases.iteritems():
|
for k, v in aliases.items():
|
||||||
if v in seq_dict:
|
if v in seq_dict:
|
||||||
usable_aliases[k] = v
|
usable_aliases[k] = v
|
||||||
if k in seq_dict:
|
if k in seq_dict:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python3
|
||||||
# Copyright 2015 Google, Inc. All Rights Reserved.
|
# Copyright 2015 Google, Inc. All Rights Reserved.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python3
|
||||||
#
|
#
|
||||||
# Copyright 2016 Google Inc. All rights reserved.
|
# Copyright 2016 Google Inc. All rights reserved.
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python3
|
||||||
# Copyright 2015 Google, Inc. All Rights Reserved.
|
# Copyright 2015 Google, Inc. All Rights Reserved.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python3
|
||||||
#
|
#
|
||||||
# Copyright 2014 Google Inc. All rights reserved.
|
# Copyright 2014 Google Inc. All rights reserved.
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python3
|
||||||
#
|
#
|
||||||
# Copyright 2016 Google Inc. All rights reserved.
|
# Copyright 2016 Google Inc. All rights reserved.
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python3
|
||||||
#
|
#
|
||||||
# Copyright 2015 Google Inc. All rights reserved.
|
# Copyright 2015 Google Inc. All rights reserved.
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python3
|
||||||
#
|
#
|
||||||
# Copyright 2016 Google Inc. All rights reserved.
|
# Copyright 2016 Google Inc. All rights reserved.
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-#
|
# -*- coding: utf-8 -*-#
|
||||||
#
|
#
|
||||||
# Copyright 2015 Google Inc. All rights reserved.
|
# Copyright 2015 Google Inc. All rights reserved.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python3
|
||||||
# Copyright 2017 Google Inc. All rights reserved.
|
# Copyright 2017 Google Inc. All rights reserved.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python3
|
||||||
# Copyright 2015 Google, Inc. All Rights Reserved.
|
# Copyright 2015 Google, Inc. All Rights Reserved.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python3
|
||||||
#
|
#
|
||||||
# Copyright 2014 Google Inc. All rights reserved.
|
# Copyright 2014 Google Inc. All rights reserved.
|
||||||
#
|
#
|
||||||
|
@ -19,6 +19,7 @@
|
||||||
__author__ = 'roozbeh@google.com (Roozbeh Pournader)'
|
__author__ = 'roozbeh@google.com (Roozbeh Pournader)'
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
import itertools
|
||||||
|
|
||||||
from fontTools import ttLib
|
from fontTools import ttLib
|
||||||
|
|
||||||
|
@ -53,8 +54,9 @@ def add_pua_cmap(source_file, target_file):
|
||||||
"""Add PUA characters to the cmap of the first font and save as second."""
|
"""Add PUA characters to the cmap of the first font and save as second."""
|
||||||
font = ttLib.TTFont(source_file)
|
font = ttLib.TTFont(source_file)
|
||||||
cmap = font_data.get_cmap(font)
|
cmap = font_data.get_cmap(font)
|
||||||
for pua, (ch1, ch2) in (add_emoji_gsub.EMOJI_KEYCAPS.items()
|
for pua, (ch1, ch2) in itertools.chain(
|
||||||
+ add_emoji_gsub.EMOJI_FLAGS.items()):
|
add_emoji_gsub.EMOJI_KEYCAPS.items(), add_emoji_gsub.EMOJI_FLAGS.items()
|
||||||
|
):
|
||||||
if pua not in cmap:
|
if pua not in cmap:
|
||||||
glyph_name = get_glyph_name_from_gsub([ch1, ch2], font)
|
glyph_name = get_glyph_name_from_gsub([ch1, ch2], font)
|
||||||
if glyph_name is not None:
|
if glyph_name is not None:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python3
|
||||||
#
|
#
|
||||||
# Copyright 2016 Google Inc. All rights reserved.
|
# Copyright 2016 Google Inc. All rights reserved.
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python3
|
||||||
#
|
#
|
||||||
# Copyright 2017 Google Inc. All rights reserved.
|
# Copyright 2017 Google Inc. All rights reserved.
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python3
|
||||||
# Copyright 2015 Google, Inc. All Rights Reserved.
|
# Copyright 2015 Google, Inc. All Rights Reserved.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
55
third_party/color_emoji/emoji_builder.py
vendored
55
third_party/color_emoji/emoji_builder.py
vendored
|
@ -19,13 +19,19 @@
|
||||||
|
|
||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
import sys, struct, StringIO
|
import sys, struct
|
||||||
from png import PNG
|
from png import PNG
|
||||||
import os
|
import os
|
||||||
from os import path
|
from os import path
|
||||||
|
|
||||||
from nototools import font_data
|
from nototools import font_data
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
unichr # py2
|
||||||
|
except NameError:
|
||||||
|
unichr = chr # py3
|
||||||
|
|
||||||
def get_glyph_name_from_gsub (string, font, cmap_dict):
|
def get_glyph_name_from_gsub (string, font, cmap_dict):
|
||||||
ligatures = font['GSUB'].table.LookupList.Lookup[0].SubTable[0].ligatures
|
ligatures = font['GSUB'].table.LookupList.Lookup[0].SubTable[0].ligatures
|
||||||
first_glyph = cmap_dict[ord (string[0])]
|
first_glyph = cmap_dict[ord (string[0])]
|
||||||
|
@ -112,9 +118,9 @@ class CBDT:
|
||||||
line_height = (ascent + descent) * y_ppem / float (upem)
|
line_height = (ascent + descent) * y_ppem / float (upem)
|
||||||
line_ascent = ascent * y_ppem / float (upem)
|
line_ascent = ascent * y_ppem / float (upem)
|
||||||
y_bearing = int (round (line_ascent - .5 * (line_height - height)))
|
y_bearing = int (round (line_ascent - .5 * (line_height - height)))
|
||||||
# fudge y_bearing if calculations are a bit off
|
# fudge y_bearing if calculations are a bit off
|
||||||
if y_bearing == 128:
|
if y_bearing == 128:
|
||||||
y_bearing = 127
|
y_bearing = 127
|
||||||
advance = width
|
advance = width
|
||||||
|
|
||||||
vert_x_bearing = - width / 2
|
vert_x_bearing = - width / 2
|
||||||
|
@ -133,22 +139,22 @@ class CBDT:
|
||||||
# CHAR vertBearingX
|
# CHAR vertBearingX
|
||||||
# CHAR vertBearingY
|
# CHAR vertBearingY
|
||||||
# BYTE vertAdvance
|
# BYTE vertAdvance
|
||||||
try:
|
try:
|
||||||
if big_metrics:
|
if big_metrics:
|
||||||
self.write (struct.pack ("BBbbBbbB",
|
self.write (struct.pack ("BBbbBbbB",
|
||||||
height, width,
|
height, width,
|
||||||
x_bearing, y_bearing,
|
x_bearing, y_bearing,
|
||||||
advance,
|
advance,
|
||||||
vert_x_bearing, vert_y_bearing,
|
vert_x_bearing, vert_y_bearing,
|
||||||
vert_advance))
|
vert_advance))
|
||||||
else:
|
else:
|
||||||
self.write (struct.pack ("BBbbB",
|
self.write (struct.pack ("BBbbB",
|
||||||
height, width,
|
height, width,
|
||||||
x_bearing, y_bearing,
|
x_bearing, y_bearing,
|
||||||
advance))
|
advance))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise ValueError("%s, h: %d w: %d x: %d y: %d %d a:" % (
|
raise ValueError("%s, h: %d w: %d x: %d y: %d %d a:" % (
|
||||||
e, height, width, x_bearing, y_bearing, advance))
|
e, height, width, x_bearing, y_bearing, advance))
|
||||||
|
|
||||||
def write_format1 (self, png):
|
def write_format1 (self, png):
|
||||||
|
|
||||||
|
@ -179,12 +185,12 @@ class CBDT:
|
||||||
self.write (pixel)
|
self.write (pixel)
|
||||||
offset += stride
|
offset += stride
|
||||||
|
|
||||||
png_allowed_chunks = ["IHDR", "PLTE", "tRNS", "sRGB", "IDAT", "IEND"]
|
png_allowed_chunks = [b"IHDR", b"PLTE", b"tRNS", b"sRGB", b"IDAT", b"IEND"]
|
||||||
|
|
||||||
def write_format17 (self, png):
|
def write_format17 (self, png):
|
||||||
self.write_format17or18(png, False)
|
self.write_format17or18(png, False)
|
||||||
|
|
||||||
def write_format18 (self, png):
|
def write_format18 (self, png):
|
||||||
self.write_format17or18(png, True)
|
self.write_format17or18(png, True)
|
||||||
|
|
||||||
def write_format17or18 (self, png, big_metrics):
|
def write_format17or18 (self, png, big_metrics):
|
||||||
|
@ -202,7 +208,7 @@ class CBDT:
|
||||||
|
|
||||||
def image_write_func (self, image_format):
|
def image_write_func (self, image_format):
|
||||||
if image_format == 1: return self.write_format1
|
if image_format == 1: return self.write_format1
|
||||||
if image_format == 17: return self.write_format17
|
if image_format == 17: return self.write_format17
|
||||||
if image_format == 18: return self.write_format18
|
if image_format == 18: return self.write_format18
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -441,7 +447,7 @@ By default they are dropped.
|
||||||
|
|
||||||
def add_font_table (font, tag, data):
|
def add_font_table (font, tag, data):
|
||||||
tab = ttLib.tables.DefaultTable.DefaultTable (tag)
|
tab = ttLib.tables.DefaultTable.DefaultTable (tag)
|
||||||
tab.data = str(data)
|
tab.data = data
|
||||||
font[tag] = tab
|
font[tag] = tab
|
||||||
|
|
||||||
def drop_outline_tables (font):
|
def drop_outline_tables (font):
|
||||||
|
@ -478,7 +484,7 @@ By default they are dropped.
|
||||||
eblc.write_header ()
|
eblc.write_header ()
|
||||||
eblc.start_strikes (len (img_prefixes))
|
eblc.start_strikes (len (img_prefixes))
|
||||||
|
|
||||||
def is_vs(cp):
|
def is_vs(cp):
|
||||||
return cp >= 0xfe00 and cp <= 0xfe0f
|
return cp >= 0xfe00 and cp <= 0xfe0f
|
||||||
|
|
||||||
for img_prefix in img_prefixes:
|
for img_prefix in img_prefixes:
|
||||||
|
@ -491,13 +497,13 @@ By default they are dropped.
|
||||||
codes = img_file[len (img_prefix):-4]
|
codes = img_file[len (img_prefix):-4]
|
||||||
if "_" in codes:
|
if "_" in codes:
|
||||||
pieces = codes.split ("_")
|
pieces = codes.split ("_")
|
||||||
cps = [int(code, 16) for code in pieces]
|
cps = [int(code, 16) for code in pieces]
|
||||||
uchars = "".join ([unichr(cp) for cp in cps if not is_vs(cp)])
|
uchars = "".join (unichr(cp) for cp in cps if not is_vs(cp))
|
||||||
else:
|
else:
|
||||||
cp = int(codes, 16)
|
cp = int(codes, 16)
|
||||||
if is_vs(cp):
|
if is_vs(cp):
|
||||||
print("ignoring unexpected vs input %04x" % cp)
|
print("ignoring unexpected vs input %04x" % cp)
|
||||||
continue
|
continue
|
||||||
uchars = unichr(cp)
|
uchars = unichr(cp)
|
||||||
img_files[uchars] = img_file
|
img_files[uchars] = img_file
|
||||||
if not img_files:
|
if not img_files:
|
||||||
|
@ -561,8 +567,7 @@ By default they are dropped.
|
||||||
# hack removal of cmap pua entry for unknown flag glyph. If we try to
|
# hack removal of cmap pua entry for unknown flag glyph. If we try to
|
||||||
# remove it earlier, getGlyphID dies. Need to restructure all of this
|
# remove it earlier, getGlyphID dies. Need to restructure all of this
|
||||||
# code.
|
# code.
|
||||||
font_data.delete_from_cmap(font, [0xfe82b])
|
font_data.delete_from_cmap(font, [0xfe82b])
|
||||||
|
|
||||||
font.save (out_file)
|
font.save (out_file)
|
||||||
print("Output font '%s' generated." % out_file)
|
print("Output font '%s' generated." % out_file)
|
||||||
|
|
||||||
|
|
19
third_party/color_emoji/png.py
vendored
19
third_party/color_emoji/png.py
vendored
|
@ -17,7 +17,15 @@
|
||||||
# Google Author(s): Behdad Esfahbod
|
# Google Author(s): Behdad Esfahbod
|
||||||
#
|
#
|
||||||
|
|
||||||
import struct, StringIO
|
import struct
|
||||||
|
import sys
|
||||||
|
from io import BytesIO
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
basestring # py2
|
||||||
|
except NameError:
|
||||||
|
basestring = str # py3
|
||||||
|
|
||||||
|
|
||||||
class PNG:
|
class PNG:
|
||||||
|
@ -55,7 +63,8 @@ class PNG:
|
||||||
return PNG.signature
|
return PNG.signature
|
||||||
|
|
||||||
def read_chunk (self):
|
def read_chunk (self):
|
||||||
length = struct.unpack (">I", self.f.read (4))[0]
|
buf = self.f.read (4)
|
||||||
|
length = struct.unpack (">I", buf)[0]
|
||||||
chunk_type = self.f.read (4)
|
chunk_type = self.f.read (4)
|
||||||
chunk_data = self.f.read (length)
|
chunk_data = self.f.read (length)
|
||||||
if len (chunk_data) != length:
|
if len (chunk_data) != length:
|
||||||
|
@ -67,7 +76,7 @@ class PNG:
|
||||||
|
|
||||||
def read_IHDR (self):
|
def read_IHDR (self):
|
||||||
(chunk_type, chunk_data, crc) = self.read_chunk ()
|
(chunk_type, chunk_data, crc) = self.read_chunk ()
|
||||||
if chunk_type != "IHDR":
|
if chunk_type != b"IHDR":
|
||||||
raise PNG.BadChunk
|
raise PNG.BadChunk
|
||||||
# Width: 4 bytes
|
# Width: 4 bytes
|
||||||
# Height: 4 bytes
|
# Height: 4 bytes
|
||||||
|
@ -93,7 +102,7 @@ class PNG:
|
||||||
|
|
||||||
def filter_chunks (self, chunks):
|
def filter_chunks (self, chunks):
|
||||||
self.seek (0);
|
self.seek (0);
|
||||||
out = StringIO.StringIO ()
|
out = BytesIO ()
|
||||||
out.write (self.read_signature ())
|
out.write (self.read_signature ())
|
||||||
while True:
|
while True:
|
||||||
chunk_type, chunk_data, crc = self.read_chunk ()
|
chunk_type, chunk_data, crc = self.read_chunk ()
|
||||||
|
@ -102,6 +111,6 @@ class PNG:
|
||||||
out.write (chunk_type)
|
out.write (chunk_type)
|
||||||
out.write (chunk_data)
|
out.write (chunk_data)
|
||||||
out.write (crc)
|
out.write (crc)
|
||||||
if chunk_type == "IEND":
|
if chunk_type == b"IEND":
|
||||||
break
|
break
|
||||||
return PNG (out)
|
return PNG (out)
|
||||||
|
|
Loading…
Add table
Reference in a new issue