This file is indexed.

/usr/lib/python2.7/dist-packages/reportlab/pdfgen/pdfimages.py is in python-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))