Browse Source

initial palemoon-29.4.0.2 import

basilisk-20211114
roytam1 10 months ago
commit
8d3c8f6a56
  1. 1
      .gitattributes
  2. 75
      .gitignore
  3. 3
      .gitmodules
  4. 15
      .ycm_extra_conf.py
  5. 1078
      AUTHORS
  6. 14
      LICENSE
  7. 16
      README.md
  8. 27
      aclocal.m4
  9. 76
      build/autoconf/mozconfig-find
  10. 76
      build/autoconf/mozconfig2client-mk
  11. 0
      build/dumbmake-dependencies
  12. 14
      build/mach_bootstrap.py
  13. 40
      build/pymake/make.py
  14. 3
      build/pypng/check-sync-exceptions
  15. 128
      build/pypng/exnumpy.py
  16. 537
      build/pypng/iccp.py
  17. 45
      build/pypng/mkiccp.py
  18. 99
      build/pypng/pdsimgtopng
  19. 73
      build/pypng/pipasgrey
  20. 44
      build/pypng/pipcat
  21. 56
      build/pypng/pipcolours
  22. 121
      build/pypng/pipcomposite
  23. 181
      build/pypng/pipdither
  24. 36
      build/pypng/piprgb
  25. 53
      build/pypng/pipscalez
  26. 127
      build/pypng/pipstack
  27. 67
      build/pypng/pipwindow
  28. 293
      build/pypng/plan9topng.py
  29. 172
      build/pypng/pngchunk
  30. 79
      build/pypng/pnghist
  31. 31
      build/pypng/pnglsch
  32. 151
      build/pypng/texttopng
  33. 484
      client.mk
  34. 16
      config/baseconfig.mk
  35. 7
      config/config.mk
  36. 2279
      config/configobj.py
  37. 94
      config/makefiles/autotargets.mk
  38. 117
      config/makefiles/makeutils.mk
  39. 25
      config/printconfigsetting.py
  40. 9
      config/recurse.mk
  41. 13
      config/rules.mk
  42. 38
      configure.in
  43. 32
      configure.py
  44. 4
      mach
  45. 7
      moz.build
  46. 6
      moz.configure
  47. 29
      other-licenses/7zstub/palemoon/7zSD.manifest
  48. BIN
      other-licenses/7zstub/palemoon/7zSD.sfx
  49. 7
      palemoon/LICENSE
  50. 13
      palemoon/Makefile.in
  51. 1
      palemoon/app-rules.mk
  52. 16
      palemoon/app.mozbuild
  53. 111
      palemoon/app/Makefile.in
  54. 50
      palemoon/app/application.ini
  55. 3931
      palemoon/app/blocklist.xml
  56. 1
      palemoon/app/macbuild/Contents/CodeResources
  57. 227
      palemoon/app/macbuild/Contents/Info.plist.in
  58. 11
      palemoon/app/macbuild/Contents/MacOS-files-copy.in
  59. 9
      palemoon/app/macbuild/Contents/MacOS-files.in
  60. 5
      palemoon/app/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in
  61. 71
      palemoon/app/macbuild/Contents/_CodeSignature/CodeResources
  62. 44
      palemoon/app/macversion.py
  63. 8
      palemoon/app/module.ver
  64. 66
      palemoon/app/moz.build
  65. 372
      palemoon/app/nsBrowserApp.cpp
  66. 47
      palemoon/app/palemoon.exe.manifest
  67. 14
      palemoon/app/permissions
  68. 6
      palemoon/app/profile/channel-prefs.js
  69. 6
      palemoon/app/profile/extensions/moz.build
  70. 10
      palemoon/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/Makefile.in
  71. 40
      palemoon/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf.in
  72. 7
      palemoon/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/moz.build
  73. 7
      palemoon/app/profile/pagethemes.rdf
  74. 1192
      palemoon/app/profile/palemoon.js
  75. 13
      palemoon/app/profile/prefs.js
  76. 21
      palemoon/app/splash.rc
  77. 1
      palemoon/app/ua-update.json
  78. 74
      palemoon/base/content/aboutDialog.css
  79. 55
      palemoon/base/content/aboutDialog.js
  80. 78
      palemoon/base/content/aboutDialog.xul
  81. 17
      palemoon/base/content/autocomplete.css
  82. 2112
      palemoon/base/content/autocomplete.xml
  83. 58
      palemoon/base/content/autorecovery.js
  84. 12
      palemoon/base/content/autorecovery.xul
  85. 78
      palemoon/base/content/baseMenuOverlay.xul
  86. 564
      palemoon/base/content/browser-addons.js
  87. 381
      palemoon/base/content/browser-appmenu.inc
  88. 62
      palemoon/base/content/browser-charsetmenu.inc
  89. 390
      palemoon/base/content/browser-context.inc
  90. 91
      palemoon/base/content/browser-devtools-theme.js
  91. 19
      palemoon/base/content/browser-doctype.inc
  92. 236
      palemoon/base/content/browser-feeds.js
  93. 454
      palemoon/base/content/browser-fullScreen.js
  94. 539
      palemoon/base/content/browser-fullZoom.js
  95. 1189
      palemoon/base/content/browser-gestureSupport.js
  96. 504
      palemoon/base/content/browser-menubar.inc
  97. 351
      palemoon/base/content/browser-menudragging.js
  98. 13
      palemoon/base/content/browser-menudragging.xul
  99. 1352
      palemoon/base/content/browser-places.js
  100. 789
      palemoon/base/content/browser-plugins.js
  101. Some files were not shown because too many files have changed in this diff Show More

1
.gitattributes vendored

@ -0,0 +1 @@
* -text

75
.gitignore vendored

@ -0,0 +1,75 @@
# .gitignore - List of filenames git should ignore
# Filenames that should be ignored wherever they appear
*~
*.rej
*.orig
*.pyc
*.pyo
TAGS
tags
ID
.DS_Store*
# Vim swap files.
.*.sw[a-z]
# User files that may appear at the root
/.mozconfig*
/mozconfig
/configure
/config.cache
/config.log
/.clang_complete
/mach.ini
# Empty marker file that's generated when we check out NSS
security/manager/.nss.checkout
# Build directories
/obj*/
/build-*/
# Build directories for js shell
*/_DBG.OBJ/
*/_OPT.OBJ/
# SpiderMonkey configury
js/src/configure
js/src/autom4te.cache
# SpiderMonkey test result logs
js/src/tests/results-*.html
js/src/tests/results-*.txt
# Java HTML5 parser classes
parser/html/java/htmlparser/
parser/html/java/javaparser/
# Ignore the files and directory that Eclipse IDE creates
.project
.cproject
.settings/
# Python virtualenv artifacts.
python/psutil/*.so
python/psutil/*.pyd
python/psutil/build/
# Ignore chrome.manifest files from the devtools loader
browser/devtools/chrome.manifest
toolkit/devtools/chrome.manifest
# Ignore misc files that need not be in the repo
other-licenses/7zstub/firefox/7zSD - Copy.sfx.exe
# Ignore official beta branding
browser/branding/officialbeta/
# External Projects
# Account for someone being clever with ntfs junctions or other filesystem links ;)
basilisk/
mail/
suite/
iceweasel/
calendar/
projects/*

3
.gitmodules vendored

@ -0,0 +1,3 @@
[submodule "platform"]
path = platform
url=https://repo.palemoon.org/MoonchildProductions/UXP

15
.ycm_extra_conf.py

@ -0,0 +1,15 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import imp, os, sys
old_bytecode = sys.dont_write_bytecode
sys.dont_write_bytecode = True
ycm_module = imp.load_source("_ycm_extra_conf", os.path.join("mozilla", ".ycm_extra_conf.py"))
sys.dont_write_bytecode = old_bytecode
# Expose the FlagsForFile function from mozilla/.ycm_extra_conf.py
FlagsForFile = ycm_module.FlagsForFile

1078
AUTHORS

File diff suppressed because it is too large Load Diff

14
LICENSE

@ -0,0 +1,14 @@
Please see the file toolkit/content/license.html for the copyright licensing
conditions attached to this codebase, including copies of the licenses
concerned.
For more information about source code licensing, see:
http://www.palemoon.org/licensing.shtml
You are not granted rights or licenses to the intellectual property or trademarks
of the Mozilla Foundation, Moonchild Productions, or any other party, including
without limitation the Pale Moon name or logo.
Binary versions of Pale Moon are subject to the Pale Moon redistribution license.
For more information, see: http://www.palemoon.org/redist.shtml

16
README.md

@ -0,0 +1,16 @@
# Pale Moon web browser
This is the source code for the Pale Moon web browser, an independent browser derived from Firefox/Mozilla community code. The source tree is
laid out in a "comm-central" style configuration where only the code specific to Pale Moon is kept in this repository.
The shared Unified XUL Platform source code is referenced here as a git submodule contained in the `platform/` directory and is required to build the application.
## Getting the platform sub-module
`git submodule init && git submodule update`
## Resources
* [Build Pale Moon for Windows](https://developer.palemoon.org/build/windows/)
* [Build Pale Moon for Linux](https://developer.palemoon.org/build/linux/)
* [Pale Moon home page](http://www.palemoon.org/)
* [Code of Conduct, Contributing, and UXP Coding style](https://repo.palemoon.org/MoonchildProductions/UXP/src/branch/master/docs)

27
aclocal.m4 vendored

@ -0,0 +1,27 @@
dnl
dnl Local autoconf macros used with UXP
dnl The contents of this file are under the Public Domain.
dnl
builtin(include, platform/build/autoconf/toolchain.m4)dnl
builtin(include, platform/build/autoconf/config.status.m4)dnl
builtin(include, platform/build/autoconf/nspr.m4)dnl
builtin(include, platform/build/autoconf/nss.m4)dnl
builtin(include, platform/build/autoconf/pkg.m4)dnl
builtin(include, platform/build/autoconf/codeset.m4)dnl
builtin(include, platform/build/autoconf/altoptions.m4)dnl
builtin(include, platform/build/autoconf/mozprog.m4)dnl
builtin(include, platform/build/autoconf/acwinpaths.m4)dnl
builtin(include, platform/build/autoconf/lto.m4)dnl
builtin(include, platform/build/autoconf/frameptr.m4)dnl
builtin(include, platform/build/autoconf/compiler-opts.m4)dnl
builtin(include, platform/build/autoconf/zlib.m4)dnl
builtin(include, platform/build/autoconf/expandlibs.m4)dnl
MOZ_PROG_CHECKMSYS()
# Read the user's .mozconfig script. We can't do this in
# configure.in: autoconf puts the argument parsing code above anything
# expanded from configure.in, and we need to get the configure options
# from .mozconfig in place before that argument parsing code.
dnl MOZ_READ_MOZCONFIG(platform)

76
build/autoconf/mozconfig-find

@ -0,0 +1,76 @@
#! /bin/sh
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# mozconfigfind - Loads options from .mozconfig onto configure's
# command-line. The .mozconfig file is searched for in the
# order:
# If $MOZCONFIG is set, use that.
# If one of $TOPSRCDIR/.mozconfig or $TOPSRCDIR/mozconfig exists, use it.
# If both exist, or if various legacy locations contain a mozconfig, error.
# Otherwise, use the default build options.
#
topsrcdir=$1
abspath() {
if uname -s | grep -q MINGW; then
# We have no way to figure out whether we're in gmake or pymake right
# now. gmake gives us Unix-style paths while pymake gives us Windows-style
# paths, so attempt to handle both.
regexes='^\([A-Za-z]:\|\\\\\|\/\) ^\/'
else
regexes='^\/'
fi
for regex in $regexes; do
if echo $1 | grep -q $regex; then
echo $1
return
fi
done
# If we're at this point, we have a relative path
echo `pwd`/$1
}
if [ -n "$MOZCONFIG" ] && ! [ -f "$MOZCONFIG" ]; then
echo "Specified MOZCONFIG \"$MOZCONFIG\" does not exist!" 1>&2
exit 1
fi
if [ -n "$MOZ_MYCONFIG" ]; then
echo "Your environment currently has the MOZ_MYCONFIG variable set to \"$MOZ_MYCONFIG\". MOZ_MYCONFIG is no longer supported. Please use MOZCONFIG instead." 1>&2
exit 1
fi
if [ -z "$MOZCONFIG" ] && [ -f "$topsrcdir/.mozconfig" ] && [ -f "$topsrcdir/mozconfig" ]; then
echo "Both \$topsrcdir/.mozconfig and \$topsrcdir/mozconfig are supported, but you must choose only one. Please remove the other." 1>&2
exit 1
fi
for _config in "$MOZCONFIG" \
"$topsrcdir/.mozconfig" \
"$topsrcdir/mozconfig"
do
if test -f "$_config"; then
abspath $_config
exit 0
fi
done
# We used to support a number of other implicit .mozconfig locations. We now
# detect if we were about to use any of these locations and issue an error if we
# find any.
for _config in "$topsrcdir/mozconfig.sh" \
"$topsrcdir/myconfig.sh" \
"$HOME/.mozconfig" \
"$HOME/.mozconfig.sh" \
"$HOME/.mozmyconfig.sh"
do
if test -f "$_config"; then
echo "You currently have a mozconfig at \"$_config\". This implicit location is no longer supported. Please move it to $topsrcdir/.mozconfig or specify it explicitly via \$MOZCONFIG." 1>&2
exit 1
fi
done

76
build/autoconf/mozconfig2client-mk

@ -0,0 +1,76 @@
#! /bin/sh
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# mozconfig2client-mk - Translates .mozconfig into options for client.mk.
# Prints defines to stdout.
#
# See mozconfig2configure for more details
print_header() {
cat <<EOF
# gmake
# This file is automatically generated for client.mk.
# Do not edit. Edit $FOUND_MOZCONFIG instead.
EOF
}
ac_add_options() {
for _opt
do
case "$_opt" in
--target=*)
echo $_opt | sed s/--target/CONFIG_GUESS/
;;
*)
echo "# $_opt is used by configure (not client.mk)"
;;
esac
done
}
ac_add_app_options() {
echo "# $* is used by configure (not client.mk)"
}
mk_add_options() {
for _opt
do
# Escape shell characters, space, tab, dollar, quote, backslash,
# and substitute '@<word>@' with '$(<word>)'.
_opt=`echo "$_opt" | sed -e 's/\([\"\\]\)/\\\\\1/g; s/@\([^@]*\)@/\$(\1)/g;'`
echo $_opt;
done
}
# Main
#--------------------------------------------------
scriptdir=`dirname $0`
topsrcdir=$1
# If the path changes, configure should be rerun
echo "# PATH=$PATH"
# If FOUND_MOZCONFIG isn't set, look for it and make sure the script doesn't error out
isfoundset=${FOUND_MOZCONFIG+yes}
if [ -z $isfoundset ]; then
FOUND_MOZCONFIG=`$scriptdir/mozconfig-find $topsrcdir`
if [ $? -ne 0 ]; then
echo '$(error Fix above errors before continuing.)'
else
isfoundset=yes
fi
fi
if [ -n $isfoundset ]; then
if [ "$FOUND_MOZCONFIG" ]
then
print_header
. "$FOUND_MOZCONFIG"
echo "FOUND_MOZCONFIG := $FOUND_MOZCONFIG"
fi
fi

0
build/dumbmake-dependencies

14
build/mach_bootstrap.py

@ -0,0 +1,14 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from __future__ import unicode_literals
import os, sys
def bootstrap(topsrcdir, mozilla_dir=None):
if mozilla_dir is None:
mozilla_dir = os.path.join(topsrcdir, 'platform')
sys.path[0:0] = [mozilla_dir]
import build.mach_bootstrap
return build.mach_bootstrap.bootstrap(topsrcdir, mozilla_dir)

40
build/pymake/make.py

@ -0,0 +1,40 @@
#!/usr/bin/env python
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# This is a wrapper around mozilla-central's pymake. If that isn't found then
# this uses client.py to pull it in.
import os
import sys
import subprocess
import shlex
def getpath(relpath):
thisdir = os.path.dirname(__file__)
return os.path.abspath(os.path.join(thisdir, *relpath))
PYMAKE = getpath(["..", "..", "platform", "build", "pymake", "make.py"])
def main(args):
if 'TINDERBOX_OUTPUT' in os.environ:
# When building on mozilla build slaves, execute mozmake instead. Until bug
# 978211, this is the easiest, albeit hackish, way to do this.
mozmake = os.path.join(os.path.dirname(__file__), '..', '..',
'mozmake.exe')
if os.path.exists(mozmake):
cmd = [mozmake]
cmd.extend(sys.argv[1:])
shell = os.environ.get('SHELL')
if shell and not shell.lower().endswith('.exe'):
cmd += ['SHELL=%s.exe' % shell]
sys.exit(subprocess.call(cmd))
if not os.path.exists(PYMAKE):
raise Exception("Pymake not found")
subprocess.check_call([sys.executable, PYMAKE] + args)
if __name__ == "__main__":
main(sys.argv[1:])

3
build/pypng/check-sync-exceptions

@ -0,0 +1,3 @@
# Nothing in this directory needs to be in sync with mozilla
# The contents are used only in c-c
*

128
build/pypng/exnumpy.py

@ -0,0 +1,128 @@
#!/usr/bin/env python
# $URL: http://pypng.googlecode.com/svn/trunk/code/exnumpy.py $
# $Rev: 126 $
# Numpy example.
# Original code created by Mel Raab, modified by David Jones.
'''
Example code integrating RGB PNG files, PyPNG and NumPy
(abstracted from Mel Raab's functioning code)
'''
# http://www.python.org/doc/2.4.4/lib/module-itertools.html
import itertools
import numpy
import png
''' If you have a PNG file for an RGB image,
and want to create a numpy array of data from it.
'''
# Read the file "picture.png" from the current directory. The `Reader`
# class can take a filename, a file-like object, or the byte data
# directly; this suggests alternatives such as using urllib to read
# an image from the internet:
# png.Reader(file=urllib.urlopen('http://www.libpng.org/pub/png/PngSuite/basn2c16.png'))
pngReader=png.Reader(filename='picture.png')
# Tuple unpacking, using multiple assignment, is very useful for the
# result of asDirect (and other methods).
# See
# http://docs.python.org/tutorial/introduction.html#first-steps-towards-programming
row_count, column_count, pngdata, meta = pngReader.asDirect()
bitdepth=meta['bitdepth']
plane_count=meta['planes']
# Make sure we're dealing with RGB files
assert plane_count == 3
''' Boxed row flat pixel:
list([R,G,B, R,G,B, R,G,B],
[R,G,B, R,G,B, R,G,B])
Array dimensions for this example: (2,9)
Create `image_2d` as a two-dimensional NumPy array by stacking a
sequence of 1-dimensional arrays (rows).
The NumPy array mimics PyPNG's (boxed row flat pixel) representation;
it will have dimensions ``(row_count,column_count*plane_count)``.
'''
# The use of ``numpy.uint16``, below, is to convert each row to a NumPy
# array with data type ``numpy.uint16``. This is a feature of NumPy,
# discussed further in
# http://docs.scipy.org/doc/numpy/user/basics.types.html .
# You can use avoid the explicit conversion with
# ``numpy.vstack(pngdata)``, but then NumPy will pick the array's data
# type; in practice it seems to pick ``numpy.int32``, which is large enough
# to hold any pixel value for any PNG image but uses 4 bytes per value when
# 1 or 2 would be enough.
# --- extract 001 start
image_2d = numpy.vstack(itertools.imap(numpy.uint16, pngdata))
# --- extract 001 end
# Do not be tempted to use ``numpy.asarray``; when passed an iterator
# (`pngdata` is often an iterator) it will attempt to create a size 1
# array with the iterator as its only element.
# An alternative to the above is to create the target array of the right
# shape, then populate it row by row:
if 0:
image_2d = numpy.zeros((row_count,plane_count*column_count),
dtype=numpy.uint16)
for row_index, one_boxed_row_flat_pixels in enumerate(pngdata):
image_2d[row_index,:]=one_boxed_row_flat_pixels
del pngReader
del pngdata
''' Reconfigure for easier referencing, similar to
Boxed row boxed pixel:
list([ (R,G,B), (R,G,B), (R,G,B) ],
[ (R,G,B), (R,G,B), (R,G,B) ])
Array dimensions for this example: (2,3,3)
``image_3d`` will contain the image as a three-dimensional numpy
array, having dimensions ``(row_count,column_count,plane_count)``.
'''
# --- extract 002 start
image_3d = numpy.reshape(image_2d,
(row_count,column_count,plane_count))
# --- extract 002 end
''' ============= '''
''' Convert NumPy image_3d array to PNG image file.
If the data is three-dimensional, as it is above, the best thing
to do is reshape it into a two-dimensional array with a shape of
``(row_count, column_count*plane_count)``. Because a
two-dimensional numpy array is an iterator, it can be passed
directly to the ``png.Writer.write`` method.
'''
row_count, column_count, plane_count = image_3d.shape
assert plane_count==3
pngfile = open('picture_out.png', 'wb')
try:
# This example assumes that you have 16-bit pixel values in the data
# array (that's what the ``bitdepth=16`` argument is for).
# If you don't, then the resulting PNG file will likely be
# very dark. Hey, it's only an example.
pngWriter = png.Writer(column_count, row_count,
greyscale=False,
alpha=False,
bitdepth=16)
# As of 2009-04-13 passing a numpy array that has an element type
# that is a numpy integer type (for example, the `image_3d` array has an
# element type of ``numpy.uint16``) generates a deprecation warning.
# This is probably a bug in numpy; it may go away in the future.
# The code still works despite the warning.
# See http://code.google.com/p/pypng/issues/detail?id=44
# --- extract 003 start
pngWriter.write(pngfile,
numpy.reshape(image_3d, (-1, column_count*plane_count)))
# --- extract 003 end
finally:
pngfile.close()

537
build/pypng/iccp.py

@ -0,0 +1,537 @@
#!/usr/bin/env python
# $URL: http://pypng.googlecode.com/svn/trunk/code/iccp.py $
# $Rev: 182 $
# iccp
#
# International Color Consortium Profile
#
# Tools for manipulating ICC profiles.
#
# An ICC profile can be extracted from a PNG image (iCCP chunk).
#
#
# Non-standard ICCP tags.
#
# Apple use some (widespread but) non-standard tags. These can be
# displayed in Apple's ColorSync Utility.
# - 'vcgt' (Video Card Gamma Tag). Table to load into video
# card LUT to apply gamma.
# - 'ndin' Apple display native information.
# - 'dscm' Apple multi-localized description strings.
# - 'mmod' Apple display make and model information.
#
# References
#
# [ICC 2001] ICC Specification ICC.1:2001-04 (Profile version 2.4.0)
# [ICC 2004] ICC Specification ICC.1:2004-10 (Profile version 4.2.0.0)
import struct
import png
class FormatError(Exception):
pass
class Profile:
"""An International Color Consortium Profile (ICC Profile)."""
def __init__(self):
self.rawtagtable = None
self.rawtagdict = {}
self.d = dict()
def fromFile(self, inp, name='<unknown>'):
# See [ICC 2004]
profile = inp.read(128)
if len(profile) < 128:
raise FormatError("ICC Profile is too short.")
size, = struct.unpack('>L', profile[:4])
profile += inp.read(d['size'] - len(profile))
return self.fromString(profile, name)
def fromString(self, profile, name='<unknown>'):
self.d = dict()
d = self.d
if len(profile) < 128:
raise FormatError("ICC Profile is too short.")
d.update(
zip(['size', 'preferredCMM', 'version',
'profileclass', 'colourspace', 'pcs'],
struct.unpack('>L4sL4s4s4s', profile[:24])))
if len(profile) < d['size']:
warnings.warn(
'Profile size declared to be %d, but only got %d bytes' %
(d['size'], len(profile)))
d['version'] = '%08x' % d['version']
d['created'] = readICCdatetime(profile[24:36])
d.update(
zip(['acsp', 'platform', 'flag', 'manufacturer', 'model'],
struct.unpack('>4s4s3L', profile[36:56])))
if d['acsp'] != 'acsp':
warnings.warn('acsp field not present (not an ICC Profile?).')
d['deviceattributes'] = profile[56:64]
d['intent'], = struct.unpack('>L', profile[64:68])
d['pcsilluminant'] = readICCXYZNumber(profile[68:80])
d['creator'] = profile[80:84]
d['id'] = profile[84:100]
ntags, = struct.unpack('>L', profile[128:132])
d['ntags'] = ntags
fmt = '4s2L' * ntags
# tag table
tt = struct.unpack('>' + fmt, profile[132:132+12*ntags])
tt = group(tt, 3)
# Could (should) detect 2 or more tags having the same sig. But
# we don't. Two or more tags with the same sig is illegal per
# the ICC spec.
# Convert (sig,offset,size) triples into (sig,value) pairs.
rawtag = map(lambda x: (x[0], profile[x[1]:x[1]+x[2]]), tt)
self.rawtagtable = rawtag
self.rawtagdict = dict(rawtag)
tag = dict()
# Interpret the tags whose types we know about
for sig, v in rawtag:
if sig in tag:
warnings.warn("Duplicate tag %r found. Ignoring." % sig)
continue
v = ICCdecode(v)
if v is not None:
tag[sig] = v
self.tag = tag
return self
def greyInput(self):
"""Adjust ``self.d`` dictionary for greyscale input device.
``profileclass`` is 'scnr', ``colourspace`` is 'GRAY', ``pcs``
is 'XYZ '.
"""
self.d.update(dict(profileclass='scnr',
colourspace='GRAY', pcs='XYZ '))
return self
def maybeAddDefaults(self):
if self.rawtagdict:
return
self._addTags(
cprt='Copyright unknown.',
desc='created by $URL: http://pypng.googlecode.com/svn/trunk/code/iccp.py $ $Rev: 182 $',
wtpt=D50(),
)
def addTags(self, **k):
self.maybeAddDefaults()
self._addTags(**k)
def _addTags(self, **k):
"""Helper for :meth:`addTags`."""
for tag, thing in k.items():
if not isinstance(thing, (tuple, list)):
thing = (thing,)
typetag = defaulttagtype[tag]
self.rawtagdict[tag] = encode(typetag, *thing)
return self
def write(self, out):
"""Write ICC Profile to the file."""
if not self.rawtagtable:
self.rawtagtable = self.rawtagdict.items()
tags = tagblock(self.rawtagtable)
self.writeHeader(out, 128 + len(tags))
out.write(tags)
out.flush()
return self
def writeHeader(self, out, size=999):
"""Add default values to the instance's `d` dictionary, then
write a header out onto the file stream. The size of the
profile must be specified using the `size` argument.
"""
def defaultkey(d, key, value):
"""Add ``[key]==value`` to the dictionary `d`, but only if
it does not have that key already.
"""
if key in d:
return
d[key] = value
z = '\x00' * 4
defaults = dict(preferredCMM=z,
version='02000000',
profileclass=z,
colourspace=z,
pcs='XYZ ',
created=writeICCdatetime(),
acsp='acsp',
platform=z,
flag=0,
manufacturer=z,
model=0,
deviceattributes=0,
intent=0,
pcsilluminant=encodefuns()['XYZ'](*D50()),
creator=z,
)
for k,v in defaults.items():
defaultkey(self.d, k, v)
hl = map(self.d.__getitem__,
['preferredCMM', 'version', 'profileclass', 'colourspace',
'pcs', 'created', 'acsp', 'platform', 'flag',
'manufacturer', 'model', 'deviceattributes', 'intent',
'pcsilluminant', 'creator'])
# Convert to struct.pack input
hl[1] = int(hl[1], 16)
out.write(struct.pack('>L4sL4s4s4s12s4s4sL4sLQL12s4s', size, *hl))
out.write('\x00' * 44)
return self
def encodefuns():
"""Returns a dictionary mapping ICC type signature sig to encoding
function. Each function returns a string comprising the content of
the encoded value. To form the full value, the type sig and the 4
zero bytes should be prefixed (8 bytes).
"""
def desc(ascii):
"""Return textDescription type [ICC 2001] 6.5.17. The ASCII part is
filled in with the string `ascii`, the Unicode and ScriptCode parts
are empty."""
ascii += '\x00'
l = len(ascii)
return struct.pack('>L%ds2LHB67s' % l,
l, ascii, 0, 0, 0, 0, '')
def text(ascii):
"""Return textType [ICC 2001] 6.5.18."""
return ascii + '\x00'
def curv(f=None, n=256):
"""Return a curveType, [ICC 2001] 6.5.3. If no arguments are
supplied then a TRC for a linear response is generated (no entries).
If an argument is supplied and it is a number (for *f* to be a
number it means that ``float(f)==f``) then a TRC for that
gamma value is generated.
Otherwise `f` is assumed to be a function that maps [0.0, 1.0] to
[0.0, 1.0]; an `n` element table is generated for it.
"""
if f is None:
return struct.pack('>L', 0)
try:
if float(f) == f:
return struct.pack('>LH', 1, int(round(f*2**8)))
except (TypeError, ValueError):
pass
assert n >= 2
table = []
M = float(n-1)
for i in range(n):
x = i/M
table.append(int(round(f(x) * 65535)))
return struct.pack('>L%dH' % n, n, *table)
def XYZ(*l):
return struct.pack('>3l', *map(fs15f16, l))
return locals()
# Tag type defaults.
# Most tags can only have one or a few tag types.
# When encoding, we associate a default tag type with each tag so that
# the encoding is implicit.
defaulttagtype=dict(
A2B0='mft1',
A2B1='mft1',
A2B2='mft1',
bXYZ='XYZ',
bTRC='curv',
B2A0='mft1',
B2A1='mft1',
B2A2='mft1',
calt='dtim',
targ='text',
chad='sf32',
chrm='chrm',
cprt='desc',
crdi='crdi',
dmnd='desc',
dmdd='desc',
devs='',
gamt='mft1',
kTRC='curv',
gXYZ='XYZ',
gTRC='curv',
lumi='XYZ',
meas='',
bkpt='XYZ',
wtpt='XYZ',
ncol='',
ncl2='',
resp='',
pre0='mft1',
pre1='mft1',
pre2='mft1',
desc='desc',
pseq='',
psd0='data',
psd1='data',
psd2='data',
psd3='data',
ps2s='data',
ps2i='data',
rXYZ='XYZ',
rTRC='curv',
scrd='desc',
scrn='',
tech='sig',
bfd='',
vued='desc',
view='view',
)
def encode(tsig, *l):
"""Encode a Python value as an ICC type. `tsig` is the type
signature to (the first 4 bytes of the encoded value, see [ICC 2004]
section 10.
"""
fun = encodefuns()
if tsig not in fun:
raise "No encoder for type %r." % tsig
v = fun[tsig](*l)
# Padd tsig out with spaces.
tsig = (tsig + ' ')[:4]
return tsig + '\x00'*4 + v
def tagblock(tag):
"""`tag` should be a list of (*signature*, *element*) pairs, where
*signature* (the key) is a length 4 string, and *element* is the
content of the tag element (another string).
The entire tag block (consisting of first a table and then the
element data) is constructed and returned as a string.
"""
n = len(tag)
tablelen = 12*n
# Build the tag table in two parts. A list of 12-byte tags, and a
# string of element data. Offset is the offset from the start of
# the profile to the start of the element data (so the offset for
# the next element is this offset plus the length of the element
# string so far).
offset = 128 + tablelen + 4
# The table. As a string.
table = ''
# The element data
element = ''
for k,v in tag:
table += struct.pack('>4s2L', k, offset + len(element), len(v))
element += v
return struct.pack('>L', n) + table + element
def iccp(out, inp):
profile = Profile().fromString(*profileFromPNG(inp))
print >>out, profile.d
print >>out, map(lambda x: x[0], profile.rawtagtable)
print >>out, profile.tag
def profileFromPNG(inp):
"""Extract profile from PNG file. Return (*profile*, *name*)
pair."""
r = png.Reader(file=inp)
_,chunk = r.chunk('iCCP')
i = chunk.index('\x00')
name = chunk[:i]
compression = chunk[i+1]
assert compression == chr(0)
profile = chunk[i+2:].decode('zlib')
return profile, name
def iccpout(out, inp):
"""Extract ICC Profile from PNG file `inp` and write it to
the file `out`."""
out.write(profileFromPNG(inp)[0])
def fs15f16(x):
"""Convert float to ICC s15Fixed16Number (as a Python ``int``)."""
return int(round(x * 2**16))
def D50():
"""Return D50 illuminant as an (X,Y,Z) triple."""
# See [ICC 2001] A.1
return (0.9642, 1.0000, 0.8249)
def writeICCdatetime(t=None):
"""`t` should be a gmtime tuple (as returned from
``time.gmtime()``). If not supplied, the current time will be used.
Return an ICC dateTimeNumber in a 12 byte string.
"""
import time
if t is None:
t = time.gmtime()
return struct.pack('>6H', *t[:6])
def readICCdatetime(s):
"""Convert from 12 byte ICC representation of dateTimeNumber to
ISO8601 string. See [ICC 2004] 5.1.1"""
return '%04d-%02d-%02dT%02d:%02d:%02dZ' % struct.unpack('>6H', s)
def readICCXYZNumber(s):
"""Convert from 12 byte ICC representation of XYZNumber to (x,y,z)
triple of floats. See [ICC 2004] 5.1.11"""
return s15f16l(s)
def s15f16l(s):
"""Convert sequence of ICC s15Fixed16 to list of float."""
# Note: As long as float has at least 32 bits of mantissa, all
# values are preserved.
n = len(s)//4
t = struct.unpack('>%dl' % n, s)
return map((2**-16).__mul__, t)
# Several types and their byte encodings are defined by [ICC 2004]
# section 10. When encoded, a value begins with a 4 byte type
# signature. We use the same 4 byte type signature in the names of the
# Python functions that decode the type into a Pythonic representation.
def ICCdecode(s):
"""Take an ICC encoded tag, and dispatch on its type signature
(first 4 bytes) to decode it into a Python value. Pair (*sig*,
*value*) is returned, where *sig* is a 4 byte string, and *value* is
some Python value determined by the content and type.
"""
sig = s[0:4].strip()
f=dict(text=RDtext,
XYZ=RDXYZ,
curv=RDcurv,
vcgt=RDvcgt,
sf32=RDsf32,
)
if sig not in f:
return None
return (sig, f[sig](s))
def RDXYZ(s):
"""Convert ICC XYZType to rank 1 array of trimulus values."""
# See [ICC 2001] 6.5.26
assert s[0:4] == 'XYZ '
return readICCXYZNumber(s[8:])
def RDsf32(s):
"""Convert ICC s15Fixed16ArrayType to list of float."""
# See [ICC 2004] 10.18
assert s[0:4] == 'sf32'
return s15f16l(s[8:])
def RDmluc(s):
"""Convert ICC multiLocalizedUnicodeType. This types encodes
several strings together with a language/country code for each
string. A list of (*lc*, *string*) pairs is returned where *lc* is
the 4 byte language/country code, and *string* is the string
corresponding to that code. It seems unlikely that the same
language/country code will appear more than once with different
strings, but the ICC standard does not prohibit it."""
# See [ICC 2004] 10.13
assert s[0:4] == 'mluc'
n,sz = struct.unpack('>2L', s[8:16])
assert sz == 12
record = []
for i in range(n):
lc,l,o = struct.unpack('4s2L', s[16+12*n:28+12*n])
record.append(lc, s[o:o+l])
# How are strings encoded?
return record
def RDtext(s):
"""Convert ICC textType to Python string."""
# Note: type not specified or used in [ICC 2004], only in older
# [ICC 2001].
# See [ICC 2001] 6.5.18
assert s[0:4] == 'text'
return s[8:-1]
def RDcurv(s):
"""Convert ICC curveType."""
# See [ICC 2001] 6.5.3
assert s[0:4] == 'curv'
count, = struct.unpack('>L', s[8:12])
if count == 0:
return dict(gamma=1)
table = struct.unpack('>%dH' % count, s[12:])
if count == 1:
return dict(gamma=table[0]*2**-8)
return table
def RDvcgt(s):
"""Convert Apple CMVideoCardGammaType."""
# See
# http://developer.apple.com/documentation/GraphicsImaging/Reference/ColorSync_Manager/Reference/reference.html#//apple_ref/c/tdef/CMVideoCardGammaType
assert s[0:4] == 'vcgt'
tagtype, = struct.unpack('>L', s[8:12])
if tagtype != 0:
return s[8:]
if tagtype == 0:
# Table.
channels,count,size = struct.unpack('>3H', s[12:18])
if size == 1:
fmt = 'B'
elif size == 2:
fmt = 'H'
else:
return s[8:]
l = len(s[18:])//size
t = struct.unpack('>%d%s' % (l, fmt), s[18:])
t = group(t, count)
return size, t
return s[8:]
def group(s, n):
# See
# http://www.python.org/doc/2.6/library/functions.html#zip
return zip(*[iter(s)]*n)
def main(argv=None):
import sys
from getopt import getopt
if argv is None:
argv = sys.argv
argv = argv[1:]
opt,arg = getopt(argv, 'o:')
if len(arg) > 0:
inp = open(arg[0], 'rb')
else:
inp = sys.stdin
for o,v in opt:
if o == '-o':
f = open(v, 'wb')
return iccpout(f, inp)
return iccp(sys.stdout, inp)
if __name__ == '__main__':
main()

45
build/pypng/mkiccp.py

@ -0,0 +1,45 @@
#!/usr/bin/env python
# $URL: http://pypng.googlecode.com/svn/trunk/code/mkiccp.py $
# $Rev: 182 $
# Make ICC Profile
# References
#
# [ICC 2001] ICC Specification ICC.1:2001-04 (Profile version 2.4.0)
# [ICC 2004] ICC Specification ICC.1:2004-10 (Profile version 4.2.0.0)
import struct
# Local module.
import iccp
def black(m):
"""Return a function that maps all values from [0.0,m] to 0, and maps
the range [m,1.0] into [0.0, 1.0] linearly.
"""
m = float(m)
def f(x):
if x <= m:
return 0.0
return (x-m)/(1.0-m)
return f
# For monochrome input the required tags are (See [ICC 2001] 6.3.1.1):
# profileDescription [ICC 2001] 6.4.32
# grayTRC [ICC 2001] 6.4.19
# mediaWhitePoint [ICC 2001] 6.4.25
# copyright [ICC 2001] 6.4.13
def agreyprofile(out):
it = iccp.Profile().greyInput()
it.addTags(kTRC=black(0.07))
it.write(out)
def main():
import sys
agreyprofile(sys.stdout)
if __name__ == '__main__':
main()

99
build/pypng/pdsimgtopng

@ -0,0 +1,99 @@
#!/usr/bin/env python
# $URL: http://pypng.googlecode.com/svn/trunk/code/pdsimgtopng $
# $Rev: 154 $
# PDS Image to PNG
import re
import struct
import png
class FormatError(Exception):
pass
def pdskey(s, k):
"""Lookup key `k` in string `s`. Returns value (as a string), or
raises exception if not found.
"""
assert re.match(r' *\^?[:\w]+$', k)
safere = '^' + re.escape(k) +r' *= *(\w+)'
m = re.search(safere, s, re.MULTILINE)
if not m:
raise FormatError("Can't find %s." % k)
return m.group(1)
def img(inp):
"""Open the PDS IMG file `inp` and return (*pixels*, *info*).
*pixels* is an iterator over the rows, *info* is the information
dictionary.
"""
err = __import__('sys').stderr
consumed = 1024
s = inp.read(consumed)
record_type = pdskey(s, 'RECORD_TYPE')
if record_type != 'FIXED_LENGTH':
raise FormatError(
"Can only deal with FIXED_LENGTH record type (found %s)" %
record_type)
record_bytes = int(pdskey(s,'RECORD_BYTES'))
file_records = int(pdskey(s, 'FILE_RECORDS'))
label_records = int(pdskey(s, 'LABEL_RECORDS'))
remaining = label_records * record_bytes - consumed
s += inp.read(remaining)
consumed += remaining
image_pointer = int(pdskey(s, '^IMAGE'))
# "^IMAGE" locates a record. Records are numbered starting from 1.
image_index = image_pointer - 1
image_offset = image_index * record_bytes
gap = image_offset - consumed
assert gap >= 0
if gap:
inp.read(gap)
# This assumes there is only one OBJECT in the file, and it is the
# IMAGE.
height = int(pdskey(s, ' LINES'))
width = int(pdskey(s, ' LINE_SAMPLES'))
sample_type = pdskey(s, ' SAMPLE_TYPE')
sample_bits = int(pdskey(s, ' SAMPLE_BITS'))
# For Messenger MDIS, SAMPLE_BITS is reported as 16, but only values
# from 0 ot 4095 are used.
bitdepth = 12
if sample_type == 'MSB_UNSIGNED_INTEGER':
fmt = '>H'
else:
raise 'Unknown sample type: %s.' % sample_type
sample_bytes = (1,2)[bitdepth > 8]
row_bytes = sample_bytes * width
fmt = fmt[:1] + str(width) + fmt[1:]
def rowiter():
for y in range(height):
yield struct.unpack(fmt, inp.read(row_bytes))
info = dict(greyscale=True, alpha=False, bitdepth=bitdepth,
size=(width,height), gamma=1.0)
return rowiter(), info
def main(argv=None):
import sys
if argv is None:
argv = sys.argv
argv = argv[1:]
arg = argv
if len(arg) >= 1:
f = open(arg[0], 'rb')
else:
f = sys.stdin
pixels,info = img(f)
w = png.Writer(**info)
w.write(sys.stdout, pixels)
if __name__ == '__main__':
main()

73
build/pypng/pipasgrey

@ -0,0 +1,73 @@
#!/usr/bin/env python
# $URL: http://pypng.googlecode.com/svn/trunk/code/pipasgrey $
# $Rev: 187 $
# pipasgrey
# Convert image to grey (L, or LA), but only if that involves no colour
# change.
def asgrey(out, inp, quiet=False):
"""Convert image to greyscale, but only when no colour change. This
works by using the input G channel (green) as the output L channel
(luminance) and checking that every pixel is grey as we go. A non-grey
pixel will raise an error, but if `quiet` is true then the grey pixel
check is suppressed.
"""
from array import array
import png
r = png.Reader(file=inp)
_,_,pixels,info = r.asDirect()
if info['greyscale']:
w = png.Writer(**info)
return w.write(out, pixels)
planes = info['planes']
targetplanes = planes - 2
alpha = info['alpha']
width = info['size'][0]
typecode = 'BH'[info['bitdepth'] > 8]
# Values per target row
vpr = width * (targetplanes)
def iterasgrey():
for i,row in enumerate(pixels):
row = array(typecode, row)
targetrow = array(typecode, [0]*vpr)
# Copy G (and possibly A) channel.
green = row[0::planes]
if alpha:
targetrow[0::2] = green
targetrow[1::2] = row[3::4]
else:
targetrow = green
# Check R and B channel match.
if not quiet and (
green != row[0::planes] or green != row[2::planes]):
raise ValueError('Row %i contains non-grey pixel.' % i)
yield targetrow
info['greyscale'] = True
del info['planes']
w = png.Writer(**info)
w.write(out, iterasgrey())
def main(argv=None):
from getopt import getopt
import sys
if argv is None:
argv = sys.argv
argv = argv[1:]
opt,argv = getopt(argv, 'q')
quiet = False
for o,v in opt:
if o == '-q':
quiet = True
if len(argv) > 0:
f = open(argv[0], 'rb')
else:
f = sys.stdin
return asgrey(sys.stdout, f, quiet)
if __name__ == '__main__':
main()

44
build/pypng/pipcat

@ -0,0 +1,44 @@
#!/usr/bin/env python
# $URL: http://pypng.googlecode.com/svn/trunk/code/pipcat $
# $Rev: 77 $
# http://www.python.org/doc/2.4.4/lib/module-itertools.html
import itertools
import sys
import png
def cat(out, l):
"""Concatenate the list of images. All input images must be same
height and have the same number of channels. They are concatenated
left-to-right. `out` is the (open file) destination for the
output image. `l` should be a list of open files (the input
image files).
"""
l = map(lambda f: png.Reader(file=f), l)
# Ewgh, side effects.
map(lambda r: r.preamble(), l)
# The reference height; from the first image.
height = l[0].height
# The total target width
width = 0
for i,r in enumerate(l):
if r.height != height:
raise Error('Image %d, height %d, does not match %d.' %
(i, r.height, height))
width += r.width
pixel,info = zip(*map(lambda r: r.asDirect()[2:4], l))
tinfo = dict(info[0])
del tinfo['size']
w = png.Writer(width, height, **tinfo)
def itercat():
for row in itertools.izip(*pixel):
yield itertools.chain(*row)
w.write(out, itercat())
def main(argv):
return cat(sys.stdout, map(lambda n: open(n, 'rb'), argv[1:]))
if __name__ == '__main__':
main(sys.argv)

56
build/pypng/pipcolours

@ -0,0 +1,56 @@
#!/usr/bin/env python
# $URL: http://pypng.googlecode.com/svn/trunk/code/pipcolours $
# $Rev: 96 $
# pipcolours - extract all colours present in source image.
def colours(out, inp):
import itertools
import png
r = png.Reader(file=inp)
_,_,pixels,info = r.asDirect()
planes = info['planes']
col = set()
for row in pixels:
# Ewgh, side effects on col
map(col.add, png.group(row, planes))
col,planes = channel_reduce(col, planes)
col = list(col)
col.sort()
col = list(itertools.chain(*col))
width = len(col)//planes
greyscale = planes in (1,2)
alpha = planes in (2,4)
bitdepth = info['bitdepth']
w = png.Writer(width, 1,
bitdepth=bitdepth, greyscale=greyscale, alpha=alpha)
w.write(out, [col])
def channel_reduce(col, planes):
"""Attempt to reduce the number of channels in the set of
colours."""
if planes >= 3:
def isgrey(c):
return c[0] == c[1] == c[2]
if min(map(isgrey, col)) == True:
# Every colour is grey.
col = set(map(lambda x: x[0::3], col))
planes -= 2
return col,planes
def main(argv=None):
import sys
if argv is None:
argv = sys.argv
argv = argv[1:]
if len(argv) > 0:
f = open(argv[0], 'rb')
else:
f = sys.stdin
return colours(sys.stdout, f)
if __name__ == '__main__':
main()

121
build/pypng/pipcomposite

@ -0,0 +1,121 @@
#!/usr/bin/env python
# $URL: http://pypng.googlecode.com/svn/trunk/code/pipcomposite $
# $Rev: 208 $
# pipcomposite
# Image alpha compositing.
"""
pipcomposite [--background #rrggbb] file.png
Composite an image onto a background and output the result. The
background colour is specified with an HTML-style triple (3, 6, or 12
hex digits), and defaults to black (#000).
The output PNG has no alpha channel.
It is valid for the input to have no alpha channel, but it doesn't
make much sense: the output will equal the input.
"""
import sys
def composite(out, inp, background):
import png
p = png.Reader(file=inp)
w,h,pixel,info = p.asRGBA()
outinfo = dict(info)
outinfo['alpha'] = False
outinfo['planes'] -= 1
outinfo['interlace'] = 0
# Convert to tuple and normalise to same range as source.
background = rgbhex(background)
maxval = float(2**info['bitdepth'] - 1)
background = map(lambda x: int(0.5 + x*maxval/65535.0),
background)
# Repeat background so that it's a whole row of sample values.
background *= w
def iterrow():
for row in pixel:
# Remove alpha from row, then create a list with one alpha
# entry _per channel value_.
# Squirrel the alpha channel away (and normalise it).
t = map(lambda x: x/maxval, row[3::4])
row = list(row)
del row[3::4]
alpha = row[:]
for i in range(3):
alpha[i::3] = t
assert len(alpha) == len(row) == len(background)