Example #1
0
 def from_raw(self, data, width, height, x_offset=0, y_offset=0, pal=None):
     """Load a raw 8-bpp image, converting to the Doom picture format
     (used by all graphics except flats)"""
     pal = pal or palette.default
     trans = chr(pal.tran_index)
     # First pass: extract pixel data in column+post format
     columns_in = [data[n:width*height:width] for n in range(width)]
     columns_out = []
     for column in columns_in:
         # Split into chunks of continuous non-transparent pixels
         postdata = filter(None, column.split(trans))
         # Find the y position where each chunk starts
         start_rows = []
         in_trans = True
         for y in range(height):
             if column[y] == trans:
                 in_trans = True
             elif in_trans:
                 start_rows.append(y)
                 in_trans = False
         columns_out.append(zip(start_rows, postdata))
     # Second pass: compile column+post data, adding pointers
     data = []
     columnptrs = []
     pointer = 4*width + 8
     for column in columns_out:
         columnptrs.append(util.pack('l', pointer))
         for row, pixels in column:
             data.append("%c%c\x00%s\x00" % (row, len(pixels), pixels))
             pointer += 4 + len(pixels)
         data.append('\xff')
         pointer += 1
     # Merge everything together
     self.data = ''.join([util.pack('4h', width, height, x_offset, y_offset),
                 ''.join(columnptrs), ''.join(data)])
Example #2
0
 def from_raw(self, data, width, height, x_offset=0, y_offset=0, pal=None):
     """Load a raw 8-bpp image, converting to the Doom picture format
     (used by all graphics except flats)"""
     pal = pal or palette.default
     trans = chr(pal.tran_index)
     # First pass: extract pixel data in column+post format
     columns_in = [data[n:width * height:width] for n in range(width)]
     columns_out = []
     for column in columns_in:
         # Split into chunks of continuous non-transparent pixels
         postdata = filter(None, column.split(trans))
         # Find the y position where each chunk starts
         start_rows = []
         in_trans = True
         for y in range(height):
             if column[y] == trans:
                 in_trans = True
             elif in_trans:
                 start_rows.append(y)
                 in_trans = False
         columns_out.append(zip(start_rows, postdata))
     # Second pass: compile column+post data, adding pointers
     data = []
     columnptrs = []
     pointer = 4 * width + 8
     for column in columns_out:
         columnptrs.append(util.pack('l', pointer))
         for row, pixels in column:
             data.append("%c%c\x00%s\x00" % (row, len(pixels), pixels))
             pointer += 4 + len(pixels)
         data.append('\xff')
         pointer += 1
     # Merge everything together
     self.data = ''.join([
         util.pack('4h', width, height, x_offset, y_offset),
         ''.join(columnptrs), ''.join(data)
     ])
Example #3
0
    def from_Image(self, im, translate=False):
        """Load from a PIL Image instance

        If the input image is 24-bit, the colors will be looked up
        in the current palette.

        If the input image is 8-bit, indices will simply be copied
        from the input image. To properly translate colors between
        palettes, set the `translate` parameter."""

        pixels = im.tostring()
        width, height = im.size
        # High resolution graphics not supported yet, so truncate
        height = min(254, height)
        xoff, yoff = (width // 2)-1, height-5
        if im.mode == "RGB":
            pixels = "".join([chr(self.palette.match(util.unpack('<BBB', \
                pixels[i*3:(i+1)*3]))) for i in range(width*height)])
        elif im.mode == 'P':
            srcpal = im.palette.tostring()
            if translate:
                R = [ord(c) for c in srcpal[0::3]]
                G = [ord(c) for c in srcpal[1::3]]
                B = [ord(c) for c in srcpal[2::3]]
                # Work around PIL bug: "RGB" loads as "BGR" from bmps (?)
                if util.filename[-4:].lower() == '.bmp':
                    srcpal = zip(B, G, R)
                else:
                    srcpal = zip(R, G, B)
                lexicon = [chr(self.palette.match(c)) for c in srcpal]
                pixels = "".join([lexicon[ord(b)] for b in pixels])
            else:
                # Simply copy pixels. However, make sure to translate
                # all colors matching the transparency color to the
                # right index. This is necessary because programs
                # aren't consistent in choice of position for the
                # transparent entry.
                packed_color = util.pack("BBB", *util.pal.tran_color)
                ri = 0
                while ri != -1:
                    ri = srcpal.find(packed_color, ri+3)
                    if not ri % 3 and ri//3 != self.palette.tran_index:
                        pixels = pixels.replace(chr(ri//3),
                            chr(self.palette.tran_index))
        else:
            raise TypeError, "image mode must be 'P' or 'RGB'"

        self.from_raw(pixels, width, height, xoff, yoff, self.palette)
Example #4
0
    def from_Image(self, im, translate=False):
        """Load from a PIL Image instance

        If the input image is 24-bit, the colors will be looked up
        in the current palette.

        If the input image is 8-bit, indices will simply be copied
        from the input image. To properly translate colors between
        palettes, set the `translate` parameter."""

        pixels = im.tostring()
        width, height = im.size
        # High resolution graphics not supported yet, so truncate
        height = min(254, height)
        xoff, yoff = (width // 2) - 1, height - 5
        if im.mode == "RGB":
            pixels = "".join([chr(self.palette.match(util.unpack('<BBB', \
                pixels[i*3:(i+1)*3]))) for i in range(width*height)])
        elif im.mode == 'P':
            srcpal = im.palette.tostring()
            if translate:
                R = [ord(c) for c in srcpal[0::3]]
                G = [ord(c) for c in srcpal[1::3]]
                B = [ord(c) for c in srcpal[2::3]]
                # Work around PIL bug: "RGB" loads as "BGR" from bmps (?)
                if util.filename[-4:].lower() == '.bmp':
                    srcpal = zip(B, G, R)
                else:
                    srcpal = zip(R, G, B)
                lexicon = [chr(self.palette.match(c)) for c in srcpal]
                pixels = "".join([lexicon[ord(b)] for b in pixels])
            else:
                # Simply copy pixels. However, make sure to translate
                # all colors matching the transparency color to the
                # right index. This is necessary because programs
                # aren't consistent in choice of position for the
                # transparent entry.
                packed_color = util.pack("BBB", *util.pal.tran_color)
                ri = 0
                while ri != -1:
                    ri = srcpal.find(packed_color, ri + 3)
                    if not ri % 3 and ri // 3 != self.palette.tran_index:
                        pixels = pixels.replace(chr(ri // 3),
                                                chr(self.palette.tran_index))
        else:
            raise TypeError, "image mode must be 'P' or 'RGB'"

        self.from_raw(pixels, width, height, xoff, yoff, self.palette)
Example #5
0
 def set_offsets(self, xy):
     """Set the (x, y) offsets of the graphic."""
     self.data = self.data[0:4] + util.pack('hh', *xy) + self.data[8:]
Example #6
0
 def set_offsets(self, xy):
     """Set the (x, y) offsets of the graphic."""
     self.data = self.data[0:4] + util.pack('hh', *xy) + self.data[8:]