2013-10-17 14:05:27 +00:00
|
|
|
#!/usr/bin/env python
|
2011-07-18 11:06:50 +00:00
|
|
|
import struct
|
2014-06-26 09:12:39 +00:00
|
|
|
import os
|
|
|
|
import os.path
|
2014-06-25 10:55:41 +00:00
|
|
|
from io import BytesIO
|
2014-06-26 09:12:39 +00:00
|
|
|
from .pdftypes import LITERALS_DCT_DECODE
|
|
|
|
from .pdfcolor import LITERAL_DEVICE_GRAY
|
|
|
|
from .pdfcolor import LITERAL_DEVICE_RGB
|
|
|
|
from .pdfcolor import LITERAL_DEVICE_CMYK
|
2011-07-18 11:06:50 +00:00
|
|
|
|
2013-11-07 08:35:04 +00:00
|
|
|
|
2011-07-18 11:06:50 +00:00
|
|
|
def align32(x):
|
2013-11-26 12:35:16 +00:00
|
|
|
return ((x+3)//4)*4
|
2011-07-18 11:06:50 +00:00
|
|
|
|
2013-11-07 08:35:04 +00:00
|
|
|
|
2011-07-18 11:06:50 +00:00
|
|
|
## BMPWriter
|
|
|
|
##
|
|
|
|
class BMPWriter(object):
|
|
|
|
|
|
|
|
def __init__(self, fp, bits, width, height):
|
|
|
|
self.fp = fp
|
|
|
|
self.bits = bits
|
|
|
|
self.width = width
|
|
|
|
self.height = height
|
|
|
|
if bits == 1:
|
|
|
|
ncols = 2
|
|
|
|
elif bits == 8:
|
|
|
|
ncols = 256
|
|
|
|
elif bits == 24:
|
|
|
|
ncols = 0
|
|
|
|
else:
|
|
|
|
raise ValueError(bits)
|
2013-11-26 12:35:16 +00:00
|
|
|
self.linesize = align32((self.width*self.bits+7)//8)
|
2011-07-18 11:06:50 +00:00
|
|
|
self.datasize = self.linesize * self.height
|
2011-11-07 14:29:24 +00:00
|
|
|
headersize = 14+40+ncols*4
|
|
|
|
info = struct.pack('<IiiHHIIIIII', 40, self.width, self.height, 1, self.bits, 0, self.datasize, 0, 0, ncols, 0)
|
2011-07-18 11:06:50 +00:00
|
|
|
assert len(info) == 40, len(info)
|
2011-11-07 14:29:24 +00:00
|
|
|
header = struct.pack('<ccIHHI', 'B', 'M', headersize+self.datasize, 0, 0, headersize)
|
2011-07-18 11:06:50 +00:00
|
|
|
assert len(header) == 14, len(header)
|
|
|
|
self.fp.write(header)
|
|
|
|
self.fp.write(info)
|
|
|
|
if ncols == 2:
|
2011-11-07 14:29:24 +00:00
|
|
|
# B&W color table
|
2013-11-07 08:35:04 +00:00
|
|
|
for i in (0, 255):
|
|
|
|
self.fp.write(struct.pack('BBBx', i, i, i))
|
2011-07-18 11:06:50 +00:00
|
|
|
elif ncols == 256:
|
2011-11-07 14:29:24 +00:00
|
|
|
# grayscale color table
|
2011-07-18 11:06:50 +00:00
|
|
|
for i in xrange(256):
|
2013-11-07 08:35:04 +00:00
|
|
|
self.fp.write(struct.pack('BBBx', i, i, i))
|
2011-07-18 11:06:50 +00:00
|
|
|
self.pos0 = self.fp.tell()
|
|
|
|
self.pos1 = self.pos0 + self.datasize
|
|
|
|
return
|
|
|
|
|
|
|
|
def write_line(self, y, data):
|
|
|
|
self.fp.seek(self.pos1 - (y+1)*self.linesize)
|
|
|
|
self.fp.write(data)
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
## ImageWriter
|
|
|
|
##
|
|
|
|
class ImageWriter(object):
|
|
|
|
|
|
|
|
def __init__(self, outdir):
|
|
|
|
self.outdir = outdir
|
2011-11-06 15:15:10 +00:00
|
|
|
if not os.path.exists(self.outdir):
|
|
|
|
os.makedirs(self.outdir)
|
2011-07-18 11:06:50 +00:00
|
|
|
return
|
|
|
|
|
|
|
|
def export_image(self, image):
|
|
|
|
stream = image.stream
|
|
|
|
filters = stream.get_filters()
|
|
|
|
(width, height) = image.srcsize
|
|
|
|
if len(filters) == 1 and filters[0] in LITERALS_DCT_DECODE:
|
|
|
|
ext = '.jpg'
|
2013-11-07 07:14:53 +00:00
|
|
|
elif (image.bits == 1 or
|
2011-07-18 11:06:50 +00:00
|
|
|
image.bits == 8 and image.colorspace in (LITERAL_DEVICE_RGB, LITERAL_DEVICE_GRAY)):
|
|
|
|
ext = '.%dx%d.bmp' % (width, height)
|
|
|
|
else:
|
|
|
|
ext = '.%d.%dx%d.img' % (image.bits, width, height)
|
|
|
|
name = image.name+ext
|
|
|
|
path = os.path.join(self.outdir, name)
|
|
|
|
fp = file(path, 'wb')
|
|
|
|
if ext == '.jpg':
|
2012-01-25 00:18:36 +00:00
|
|
|
raw_data = stream.get_rawdata()
|
|
|
|
if LITERAL_DEVICE_CMYK in image.colorspace:
|
2013-04-09 09:42:32 +00:00
|
|
|
from PIL import Image
|
|
|
|
from PIL import ImageChops
|
2014-06-25 10:55:41 +00:00
|
|
|
ifp = BytesIO(raw_data)
|
2013-11-07 07:14:53 +00:00
|
|
|
i = Image.open(ifp)
|
2012-01-25 00:18:36 +00:00
|
|
|
i = ImageChops.invert(i)
|
|
|
|
i = i.convert('RGB')
|
|
|
|
i.save(fp, 'JPEG')
|
|
|
|
else:
|
|
|
|
fp.write(raw_data)
|
2011-07-18 11:06:50 +00:00
|
|
|
elif image.bits == 1:
|
|
|
|
bmp = BMPWriter(fp, 1, width, height)
|
|
|
|
data = stream.get_data()
|
|
|
|
i = 0
|
2013-11-26 12:35:16 +00:00
|
|
|
width = (width+7)//8
|
2011-07-18 11:06:50 +00:00
|
|
|
for y in xrange(height):
|
|
|
|
bmp.write_line(y, data[i:i+width])
|
|
|
|
i += width
|
|
|
|
elif image.bits == 8 and image.colorspace is LITERAL_DEVICE_RGB:
|
|
|
|
bmp = BMPWriter(fp, 24, width, height)
|
|
|
|
data = stream.get_data()
|
|
|
|
i = 0
|
|
|
|
width = width*3
|
|
|
|
for y in xrange(height):
|
|
|
|
bmp.write_line(y, data[i:i+width])
|
|
|
|
i += width
|
|
|
|
elif image.bits == 8 and image.colorspace is LITERAL_DEVICE_GRAY:
|
|
|
|
bmp = BMPWriter(fp, 8, width, height)
|
|
|
|
data = stream.get_data()
|
|
|
|
i = 0
|
|
|
|
for y in xrange(height):
|
|
|
|
bmp.write_line(y, data[i:i+width])
|
|
|
|
i += width
|
|
|
|
else:
|
|
|
|
fp.write(stream.get_data())
|
|
|
|
fp.close()
|
|
|
|
return name
|