pax_global_header00006660000000000000000000000064121277555370014530gustar00rootroot0000000000000052 comment=142507d4c17020f95ac430cb8d6ede480c6e95ca psd-tools-packbits-142507d/000077500000000000000000000000001212775553700155225ustar00rootroot00000000000000psd-tools-packbits-142507d/.hgignore000066400000000000000000000002671212775553700173320ustar00rootroot00000000000000#projects \.idea #temp files \.pyc \.orig #os files \.DS_Store Thumbs.db #project-specific files \.tox stuff MANIFEST$ ^build \.ipynb$ ^dist ^packbits.egg-info ^\.coverage$ \.html$psd-tools-packbits-142507d/.hgtags000066400000000000000000000000551212775553700170000ustar00rootroot00000000000000b50462791f7eafca2fab24445b538a5594989fe6 0.5 psd-tools-packbits-142507d/AUTHORS.rst000066400000000000000000000000631212775553700174000ustar00rootroot00000000000000Authors ======= * Mikhail Korobov; * Stefan Klug. psd-tools-packbits-142507d/LICENSE.txt000066400000000000000000000020431212775553700173440ustar00rootroot00000000000000Copyright (c) 2013 Mikhail Korobov Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. psd-tools-packbits-142507d/MANIFEST.in000066400000000000000000000000161212775553700172550ustar00rootroot00000000000000include *.rst psd-tools-packbits-142507d/README.rst000066400000000000000000000014301212775553700172070ustar00rootroot00000000000000PackBits encoder/decoder ======================== This module implements a PackBits encoder/decoder for Python 2.x and 3.x. PackBits encoding is used in PSD and TIFF files. Installation ------------ :: pip install packbits Usage ----- Import ``packbits`` module; then use ``packbits.encode(data)`` and ``packbits.decode(data)`` functions. Contributing ------------ Development happens at github and bitbucket: * https://github.com/kmike/packbits * https://bitbucket.org/kmike/packbits The main issue tracker is at github: https://github.com/kmike/packbits/issues Feel free to submit ideas, bugs, pull requests (git or hg) or regular patches. In order to run tests, install `tox `_ and type :: tox from the source checkout. The license is MIT. psd-tools-packbits-142507d/setup.py000077500000000000000000000023571212775553700172460ustar00rootroot00000000000000#!/usr/bin/env python from distutils.core import setup import sys for cmd in ('egg_info', 'develop'): if cmd in sys.argv: from setuptools import setup setup_args = dict( name = 'packbits', version = '0.6', author = 'Mikhail Korobov', author_email = 'kmike84@gmail.com', url = 'https://github.com/kmike/packbits', description = 'PackBits encoder/decoder', long_description = open('README.rst').read(), license = 'MIT License', package_dir = {'': 'src'}, py_modules = ['packbits'], classifiers=[ 'Development Status :: 4 - Beta', 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', 'Programming Language :: Python', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.2', 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: Implementation :: CPython', 'Programming Language :: Python :: Implementation :: PyPy', 'Topic :: Software Development :: Libraries :: Python Modules', ], ) setup(**setup_args) psd-tools-packbits-142507d/src/000077500000000000000000000000001212775553700163115ustar00rootroot00000000000000psd-tools-packbits-142507d/src/packbits.py000066400000000000000000000046211212775553700204660ustar00rootroot00000000000000# -*- coding: utf-8 -*- from __future__ import absolute_import, unicode_literals, division, print_function def decode(data): """ Decodes a PackBit encoded data. """ data = bytearray(data) # <- python 2/3 compatibility fix result = bytearray() pos = 0 while pos < len(data): header_byte = data[pos] if header_byte > 127: header_byte -= 256 pos += 1 if 0 <= header_byte <= 127: result.extend(data[pos:pos+header_byte+1]) pos += header_byte+1 elif header_byte == -128: pass else: result.extend([data[pos]] * (1 - header_byte)) pos += 1 return bytes(result) def encode(data): """ Encodes data using PackBits encoding. """ if len(data) == 0: return data if len(data) == 1: return b'\x00' + data data = bytearray(data) result = bytearray() buf = bytearray() pos = 0 repeat_count = 0 MAX_LENGTH = 127 # we can safely start with RAW as empty RAW sequences # are handled by finish_raw() state = 'RAW' def finish_raw(): if len(buf) == 0: return result.append(len(buf)-1) result.extend(buf) buf[:] = bytearray() def finish_rle(): result.append(256-(repeat_count - 1)) result.append(data[pos]) while pos < len(data)-1: current_byte = data[pos] if data[pos] == data[pos+1]: if state == 'RAW': # end of RAW data finish_raw() state = 'RLE' repeat_count = 1 elif state == 'RLE': if repeat_count == MAX_LENGTH: # restart the encoding finish_rle() repeat_count = 0 # move to next byte repeat_count += 1 else: if state == 'RLE': repeat_count += 1 finish_rle() state = 'RAW' repeat_count = 0 elif state == 'RAW': if len(buf) == MAX_LENGTH: # restart the encoding finish_raw() buf.append(current_byte) pos += 1 if state == 'RAW': buf.append(data[pos]) finish_raw() else: repeat_count += 1 finish_rle() return bytes(result) psd-tools-packbits-142507d/test_packbits.py000066400000000000000000000037641212775553700207450ustar00rootroot00000000000000# -*- coding: utf-8 -*- from __future__ import absolute_import, unicode_literals import packbits DATA = b'\xFE\xAA\x02\x80\x00\x2A\xFD\xAA\x03\x80\x00\x2A\x22\xF7\xAA' RESULT = b'\xAA\xAA\xAA\x80\x00\x2A\xAA\xAA\xAA\xAA\x80\x00\x2A\x22\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA' def test_decode(): decoded = packbits.decode(DATA) assert decoded == RESULT def test_encode_decode(): encoded = packbits.encode(RESULT) decoded = packbits.decode(encoded) assert decoded == RESULT def test_encode_empty(): assert packbits.encode(b'') == b'' def test_encode_single(): encoded = packbits.encode(b'X') assert encoded == b'\x00X' assert packbits.decode(encoded) == b'X' def test_raw(): encoded = packbits.encode(b'123') assert encoded == b'\x02123' assert packbits.decode(encoded) == b'123' def test_encode2(): encoded = packbits.encode(b'112112') assert packbits.decode(encoded) == b'112112' def test_encode_switching_rle(): encoded = packbits.encode(b'1122') assert packbits.decode(encoded) == b'1122' def test_encode_long_rle(): data = b'1' * 126 encoded = packbits.encode(data) assert packbits.decode(encoded) == data def test_encode_long_rle2(): data = b'1' * 127 encoded = packbits.encode(data) assert packbits.decode(encoded) == data def test_encode_long_rle3(): data = b'1' * 128 encoded = packbits.encode(data) assert packbits.decode(encoded) == data def test_restart_rle(): data = b'1' * 127 + b'foo' encoded = packbits.encode(data) assert packbits.decode(encoded) == data def test_encode_long_raw(): data = b'12345678' * 17 encoded = packbits.encode(data) print(encoded) assert packbits.decode(encoded) == data def test_encode_long_raw(): data = b'12345678' * 16 encoded = packbits.encode(data) assert packbits.decode(encoded) == data def test_encode_long(): data = b'1' * 128 + b'12345678' * 17 encoded = packbits.encode(data) assert packbits.decode(encoded) == data psd-tools-packbits-142507d/tox.ini000066400000000000000000000001371212775553700170360ustar00rootroot00000000000000[tox] envlist = py26,py27,py32,py33,pypy [testenv] deps= pytest commands= py.test []