/usr/lib/python3/dist-packages/reportlab/pdfgen/pdfimages.py is in python3-reportlab 3.3.0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | #Copyright ReportLab Europe Ltd. 2000-2016
#see license.txt for license details
#history http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/pdfgen/pdfimages.py
__version__='3.3.0'
__doc__="""
Image functionality sliced out of canvas.py for generalization
"""
import os
import reportlab
from reportlab import rl_config
from reportlab.pdfbase import pdfutils
from reportlab.pdfbase import pdfdoc
from reportlab.lib.utils import import_zlib, haveImages, getBytesIO, isStr
from reportlab.lib.rl_accel import fp_str, asciiBase85Encode
from reportlab.lib.boxstuff import aspectRatioFix
class PDFImage:
"""Wrapper around different "image sources". You can make images
from a PIL Image object, a filename (in which case it uses PIL),
an image we previously cached (optimisation, hardly used these
days) or a JPEG (which PDF supports natively)."""
def __init__(self, image, x,y, width=None, height=None, caching=0):
self.image = image
self.x = x
self.y = y
self.width = width
self.height = height
self.filename = None
self.imageCaching = caching
# the following facts need to be determined,
# whatever the source. Declare what they are
# here for clarity.
self.colorSpace = 'DeviceRGB'
self.bitsPerComponent = 8
self.filters = []
self.source = None # JPEG or PIL, set later
self.getImageData()
def jpg_imagedata(self):
#directly process JPEG files
#open file, needs some error handling!!
fp = open(self.image, 'rb')
try:
result = self._jpg_imagedata(fp)
finally:
fp.close()
return result
def _jpg_imagedata(self,imageFile):
info = pdfutils.readJPEGInfo(imageFile)
self.source = 'JPEG'
imgwidth, imgheight = info[0], info[1]
if info[2] == 1:
colorSpace = 'DeviceGray'
elif info[2] == 3:
colorSpace = 'DeviceRGB'
else: #maybe should generate an error, is this right for CMYK?
colorSpace = 'DeviceCMYK'
imageFile.seek(0) #reset file pointer
imagedata = []
#imagedata.append('BI /Width %d /Height /BitsPerComponent 8 /ColorSpace /%s /Filter [/Filter [ /ASCII85Decode /DCTDecode] ID' % (info[0], info[1], colorSpace))
imagedata.append('BI /W %d /H %d /BPC 8 /CS /%s /F [%s/DCT] ID' % (imgwidth, imgheight, colorSpace, rl_config.useA85 and '/A85 ' or ''))
#write in blocks of (??) 60 characters per line to a list
data = imageFile.read()
if rl_config.useA85:
data = asciiBase85Encode(data)
pdfutils._chunker(data,imagedata)
imagedata.append('EI')
return (imagedata, imgwidth, imgheight)
def cache_imagedata(self):
image = self.image
if not pdfutils.cachedImageExists(image):
zlib = import_zlib()
if not zlib: return
if not haveImages: return
pdfutils.cacheImageFile(image)
#now we have one cached, slurp it in
cachedname = os.path.splitext(image)[0] + (rl_config.useA85 and '.a85' or '.bin')
imagedata = open(cachedname,'rb').readlines()
#trim off newlines...
imagedata = list(map(str.strip, imagedata))
return imagedata
def PIL_imagedata(self):
image = self.image
if image.format=='JPEG':
fp=image.fp
fp.seek(0)
return self._jpg_imagedata(fp)
self.source = 'PIL'
zlib = import_zlib()
if not zlib: return
bpc = 8
# Use the colorSpace in the image
if image.mode == 'CMYK':
myimage = image
colorSpace = 'DeviceCMYK'
bpp = 4
elif image.mode == '1':
myimage = image
colorSpace = 'DeviceGray'
bpp = 1
bpc = 1
elif image.mode == 'L':
myimage = image
colorSpace = 'DeviceGray'
bpp = 1
else:
myimage = image.convert('RGB')
colorSpace = 'RGB'
bpp = 3
imgwidth, imgheight = myimage.size
# this describes what is in the image itself
# *NB* according to the spec you can only use the short form in inline images
imagedata=['BI /W %d /H %d /BPC %d /CS /%s /F [%s/Fl] ID' % (imgwidth, imgheight, bpc, colorSpace, rl_config.useA85 and '/A85 ' or '')]
#use a flate filter and, optionally, Ascii Base 85 to compress
raw = (myimage.tobytes if hasattr(myimage,'tobytes') else myimage.tostring)()
rowstride = (imgwidth*bpc*bpp+7)>>3
assert len(raw) == rowstride*imgheight, "Wrong amount of data for image"
data = zlib.compress(raw) #this bit is very fast...
if rl_config.useA85:
data = asciiBase85Encode(data) #...sadly this may not be
#append in blocks of 60 characters
pdfutils._chunker(data,imagedata)
imagedata.append('EI')
return (imagedata, imgwidth, imgheight)
def non_jpg_imagedata(self,image):
if not self.imageCaching:
imagedata = pdfutils.cacheImageFile(image,returnInMemory=1)
else:
imagedata = self.cache_imagedata()
words = imagedata[1].split()
imgwidth = int(words[1])
imgheight = int(words[3])
return imagedata, imgwidth, imgheight
def getImageData(self,preserveAspectRatio=False):
"Gets data, height, width - whatever type of image"
image = self.image
if isStr(image):
self.filename = image
if os.path.splitext(image)[1] in ['.jpg', '.JPG', '.jpeg', '.JPEG']:
try:
imagedata, imgwidth, imgheight = self.jpg_imagedata()
except:
imagedata, imgwidth, imgheight = self.non_jpg_imagedata(image) #try for normal kind of image
else:
imagedata, imgwidth, imgheight = self.non_jpg_imagedata(image)
else:
import sys
if sys.platform[0:4] == 'java':
#jython, PIL not available
imagedata, imgwidth, imgheight = self.JAVA_imagedata()
else:
imagedata, imgwidth, imgheight = self.PIL_imagedata()
self.imageData = imagedata
self.imgwidth = imgwidth
self.imgheight = imgheight
self.width = self.width or imgwidth
self.height = self.height or imgheight
def drawInlineImage(self, canvas, preserveAspectRatio=False,anchor='sw'):
"""Draw an Image into the specified rectangle. If width and
height are omitted, they are calculated from the image size.
Also allow file names as well as images. This allows a
caching mechanism"""
width = self.width
height = self.height
if width<1e-6 or height<1e-6: return False
x,y,self.width,self.height, scaled = aspectRatioFix(preserveAspectRatio,anchor,self.x,self.y,width,height,self.imgwidth,self.imgheight)
# this says where and how big to draw it
if not canvas.bottomup: y = y+height
canvas._code.append('q %s 0 0 %s cm' % (fp_str(self.width), fp_str(self.height, x, y)))
# self._code.extend(imagedata) if >=python-1.5.2
for line in self.imageData:
canvas._code.append(line)
canvas._code.append('Q')
return True
def format(self, document):
"""Allow it to be used within pdfdoc framework. This only
defines how it is stored, not how it is drawn later."""
dict = pdfdoc.PDFDictionary()
dict['Type'] = '/XObject'
dict['Subtype'] = '/Image'
dict['Width'] = self.width
dict['Height'] = self.height
dict['BitsPerComponent'] = 8
dict['ColorSpace'] = pdfdoc.PDFName(self.colorSpace)
content = '\n'.join(self.imageData[3:-1]) + '\n'
strm = pdfdoc.PDFStream(dictionary=dict, content=content)
return strm.format(document)
if __name__=='__main__':
srcfile = os.path.join(
os.path.dirname(reportlab.__file__),
'test',
'pythonpowered.gif'
)
assert os.path.isfile(srcfile), 'image not found'
pdfdoc.LongFormat = 1
img = PDFImage(srcfile, 100, 100)
import pprint
doc = pdfdoc.PDFDocument()
print('source=',img.source)
print(img.format(doc))
|