# Path: TileStache/py3_compat.py
# def is_string_type(val):
# 
# Path: TileStache/Pixels.py
# def load_palette(file_href):
#     """ Load colors from a Photoshop .act file, return palette info.
# 
#         Return tuple is an array of [ (r, g, b), (r, g, b), ... ],
#         bit depth of the palette, and a numeric transparency index
#         or None if not defined.
#     """
#     bytes_ = urlopen(file_href).read()
#     count, t_index = unpack('!HH', bytes_[768:768+4])
#     t_index = (t_index <= 0xff) and t_index or None
# 
#     palette = []
# 
#     for offset in range(0, count):
#         if offset == t_index:
#             rgb = 0xff, 0x99, 0x00
#         else:
#             rgb = unpack('!BBB', bytes_[offset*3:(offset + 1)*3])
# 
#         palette.append(rgb)
# 
#     bits = int(ceil(log(len(palette)) / log(2)))
# 
#     return palette, bits, t_index
# 
# def apply_palette(image, palette, t_index):
#     """ Apply a palette array to an image, return a new image.
#     """
#     image = image.convert('RGBA')
#     pixels = image.tobytes()
# 
#     t_value = (t_index in range(256)) and pack('!B', t_index) or None
#     mapping = {}
#     indexes = []
# 
#     for offset in range(0, len(pixels), 4):
#         r, g, b, a = unpack('!BBBB', pixels[offset:offset+4])
# 
#         if a < 0x80 and t_value is not None:
#             # Sufficiently transparent
#             indexes.append(t_value)
#             continue
# 
#         try:
#             indexes.append(mapping[(r, g, b)])
# 
#         except KeyError:
#             # Never seen this color
#             mapping[(r, g, b)] = pack('!B', palette_color(r, g, b, palette, t_index))
# 
#         else:
#             continue
# 
#         indexes.append(mapping[(r, g, b)])
# 
#     if hasattr(Image, 'frombytes'):
#         # Image.fromstring is deprecated past Pillow 2.0
#         output = Image.frombytes('P', image.size, b''.join(indexes))
#     else:
#         # PIL still uses Image.fromstring
#         output = Image.fromstring('P', image.size, b''.join(indexes))
# 
#     bits = int(ceil(log(len(palette)) / log(2)))
# 
#     palette += [(0, 0, 0)] * (256 - len(palette))
#     palette = reduce(add, palette)
#     output.putpalette(palette)
# 
#     return output
# 
# def apply_palette256(image):
#     """ Get PIL to generate and apply an optimum 256 color palette to the given image and return it
#     """
#     return image.convert('RGB').convert('P', palette=Image.ADAPTIVE, colors=256, dither=Image.NONE)


import logging
    import Image
from sys import modules
from wsgiref.headers import Headers
from io import BytesIO
from .py3_compat import urljoin
from time import time
from .Pixels import load_palette, apply_palette, apply_palette256
    from PIL import Image
from ModestMaps.Core import Coordinate

    def setSaveOptionsJPEG(self, quality=None, optimize=None, progressive=None):
        """ Optional arguments are added to self.jpeg_options for pickup when saving.

            More information about options:
                http://effbot.org/imagingbook/format-jpeg.htm
        """
        if quality is not None:
            self.jpeg_options['quality'] = int(quality)

        if optimize is not None:
            self.jpeg_options['optimize'] = bool(optimize)

        if progressive is not None:
            self.jpeg_options['progressive'] = bool(progressive)

    def setSaveOptionsPNG(self, optimize=None, palette=None, palette256=None):
        """ Optional arguments are added to self.png_options for pickup when saving.

            Palette argument is a URL relative to the configuration file,
            and it implies bits and optional transparency options.

            More information about options:
                http://effbot.org/imagingbook/format-png.htm
        """
        if optimize is not None:
            self.png_options['optimize'] = bool(optimize)

        if palette is not None:
            palette = urljoin(self.config.dirpath, palette)

# Path: TileStache/py3_compat.py
# def is_string_type(val):
# 
# Path: TileStache/Pixels.py
# def load_palette(file_href):
#     """ Load colors from a Photoshop .act file, return palette info.
# 
#         Return tuple is an array of [ (r, g, b), (r, g, b), ... ],
#         bit depth of the palette, and a numeric transparency index
#         or None if not defined.
#     """
#     bytes_ = urlopen(file_href).read()
#     count, t_index = unpack('!HH', bytes_[768:768+4])
#     t_index = (t_index <= 0xff) and t_index or None
# 
#     palette = []
# 
#     for offset in range(0, count):
#         if offset == t_index:
#             rgb = 0xff, 0x99, 0x00
#         else:
#             rgb = unpack('!BBB', bytes_[offset*3:(offset + 1)*3])
# 
#         palette.append(rgb)
# 
#     bits = int(ceil(log(len(palette)) / log(2)))
# 
#     return palette, bits, t_index
# 
# def apply_palette(image, palette, t_index):
#     """ Apply a palette array to an image, return a new image.
#     """
#     image = image.convert('RGBA')
#     pixels = image.tobytes()
# 
#     t_value = (t_index in range(256)) and pack('!B', t_index) or None
#     mapping = {}
#     indexes = []
# 
#     for offset in range(0, len(pixels), 4):
#         r, g, b, a = unpack('!BBBB', pixels[offset:offset+4])
# 
#         if a < 0x80 and t_value is not None:
#             # Sufficiently transparent
#             indexes.append(t_value)
#             continue
# 
#         try:
#             indexes.append(mapping[(r, g, b)])
# 
#         except KeyError:
#             # Never seen this color
#             mapping[(r, g, b)] = pack('!B', palette_color(r, g, b, palette, t_index))
# 
#         else:
#             continue
# 
#         indexes.append(mapping[(r, g, b)])
# 
#     if hasattr(Image, 'frombytes'):
#         # Image.fromstring is deprecated past Pillow 2.0
#         output = Image.frombytes('P', image.size, b''.join(indexes))
#     else:
#         # PIL still uses Image.fromstring
#         output = Image.fromstring('P', image.size, b''.join(indexes))
# 
#     bits = int(ceil(log(len(palette)) / log(2)))
# 
#     palette += [(0, 0, 0)] * (256 - len(palette))
#     palette = reduce(add, palette)
#     output.putpalette(palette)
# 
#     return output
# 
# def apply_palette256(image):
#     """ Get PIL to generate and apply an optimum 256 color palette to the given image and return it
#     """
#     return image.convert('RGB').convert('P', palette=Image.ADAPTIVE, colors=256, dither=Image.NONE)


# Path: TileStache/Core.py
import logging
    import Image
from sys import modules
from wsgiref.headers import Headers
from io import BytesIO
from .py3_compat import urljoin
from time import time
from .Pixels import load_palette, apply_palette, apply_palette256
    from PIL import Image
from ModestMaps.Core import Coordinate


    def setSaveOptionsJPEG(self, quality=None, optimize=None, progressive=None):
        """ Optional arguments are added to self.jpeg_options for pickup when saving.

            More information about options:
                http://effbot.org/imagingbook/format-jpeg.htm
        """
        if quality is not None:
            self.jpeg_options['quality'] = int(quality)

        if optimize is not None:
            self.jpeg_options['optimize'] = bool(optimize)

        if progressive is not None:
            self.jpeg_options['progressive'] = bool(progressive)

    def setSaveOptionsPNG(self, optimize=None, palette=None, palette256=None):
        """ Optional arguments are added to self.png_options for pickup when saving.

            Palette argument is a URL relative to the configuration file,
            and it implies bits and optional transparency options.

            More information about options:
                http://effbot.org/imagingbook/format-png.htm
        """
        if optimize is not None:
            self.png_options['optimize'] = bool(optimize)

        if palette is not None:
            palette = urljoin(self.config.dirpath, palette)

            palette, bits, t_index = load_palette(palette)