From suresh_vsamy at rediffmail.com Wed Jul 2 17:30:09 2003 From: suresh_vsamy at rediffmail.com (Suresh Kumar) Date: Wed Jul 2 12:30:11 2003 Subject: [Image-SIG] Storing tk canvas as PNG file........... Message-ID: <20030702162752.14816.qmail@webmail26.rediffmail.com> Hi, Iam using python2.2/tkinter/windows. My doubt is regarding how to convert tkiner canvas as a PNG file? I have drawn some rectangles in my canvas. The canvas size is larger than the screen. Initially i used "ImageGrab" to grab the entire canvas. But the ImageGrab approach doesn't work in my case, since it copies pixels from the display, i couldn't able to grab the entire canvas. To overcome this problem i used Postscript generation mechanisms provided by the Canvas widget and coverted the canvas to a postscript file. In this case i converted entire canvas into a postscript file. The problem with Postscript format is, we need Ghostscript viewer to view the Postcript image which we have to install separately. Since most of the systems running under Windows OS will have "Microsoft Photo Editor", it would be nice to have a PNG file rather than PostScript file. Is there any way to store the entire canvas as a PNG file? Otherwise how can i convert a postscript file to PNG or BMP file in Python? Is it possible to convert postscript file to PNG file in python? Anyother solution.......? I need the solution urgently. Earlier replies are welcome. With Regards, V.Suresh Kumar ___________________________________________________ Click below to experience Sooraj R Barjatya's latest offering 'Main Prem Ki Diwani Hoon' starring Hrithik, Abhishek & Kareena http://www.mpkdh.com From suresh_vsamy at rediffmail.com Thu Jul 3 14:49:49 2003 From: suresh_vsamy at rediffmail.com (Suresh Kumar) Date: Thu Jul 3 09:49:50 2003 Subject: [Image-SIG] Reading an image file data......... Message-ID: <20030703134941.15069.qmail@webmail26.rediffmail.com> Hi, I scanned a page of my textbook and stored as a JPEG file. Now i want to read a text from the JPEG image which is at some location, say from (100,100) to (300,300). How can i read it? I am using PIL module for image handling and tkinter. Moreover i am new to PIL module. Is it possible to read a text from a JPEG file in python/tkinter? With Regards, V.Suresh Kumar ___________________________________________________ Click below to experience Sooraj R Barjatya's latest offering 'Main Prem Ki Diwani Hoon' starring Hrithik, Abhishek & Kareena http://www.mpkdh.com From pete at shinners.org Thu Jul 3 10:06:25 2003 From: pete at shinners.org (Pete Shinners) Date: Thu Jul 3 12:38:31 2003 Subject: [Image-SIG] Re: Reading an image file data......... In-Reply-To: <20030703134941.15069.qmail@webmail26.rediffmail.com> References: <20030703134941.15069.qmail@webmail26.rediffmail.com> Message-ID: Suresh Kumar wrote: > I scanned a page of my textbook and stored as a JPEG file. Now i want > to read a text from the JPEG image which is at some location, say from > (100,100) to (300,300). How can i read it? I am using PIL module for > image handling and tkinter. Moreover i am new to PIL module. Is it > possible to read a text from a JPEG file in python/tkinter? what you want is a process called OCR (i think it means optical character recognition, or something like that). it is the process of translating an image into plain text. it looks like on linux you have 'clara', and 'gocr', and probable a few others. you will likely need to call on these other tools to handle the OCR for you. From python at jaydorsey.com Tue Jul 8 22:09:04 2003 From: python at jaydorsey.com (Jay Dorsey) Date: Tue Jul 8 21:08:39 2003 Subject: [Image-SIG] decoder jpeg not available Message-ID: <3F0B6B30.2050400@jaydorsey.com> I could really use some assitance in troubleshooting this problem. I'm using Python 2.3a, PIL 1.1.4 on Solaris 8. I installed the jpeg libraries into the default locations (had to compile with --enable-shared and --enable-static - that threw me off for about an hour -- I'm not a Solaris guy). make test worked fine. I followed the install instructions in the README file, and used the -fpic flag when compiling in libImaging. I've followed the instructions on http://effbot.org/zone/pil-decoder-jpeg-not-available.htm (twice), with no luck (Excellent instructions/documentation however). I do receive the "checking for jpeg_destroy_compress in _ljpeg... no" message. I'm able to import _imaging. Starting with python -v and doing an >>> import Imaging shows import _imaging # dynamically loaded from _imaging.so The only thing I've found that was odd was doing 'ldd _imaging.so' doesn't show a link to libjpeg.so (or libjpeg.so.62), but I'm not quite sure if that means anything or not. Any help or suggestions are appreciated. Thank you for your time. Jay From DSIC-SDEL-NTIC2 at interieur.gouv.fr Wed Jul 9 11:54:57 2003 From: DSIC-SDEL-NTIC2 at interieur.gouv.fr (DSIC SDEL NTIC2 DSIC SDEL) Date: Wed Jul 9 05:05:02 2003 Subject: [Image-SIG] PIL installation Message-ID: <8F24A400BFCFD611AD3F00B0D0F9E9F1F8C9FE@MSG01NEL> Hello, I work for a french ministry and i would like to install PIL under windows platform. I downloaded PIL version 1.1.4 for Python 2.1. I launched file and there is nothing install. What can i do ? I am on windows 2000 professionnal. Thank your for your help DB -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.python.org/pipermail/image-sig/attachments/20030709/fe429b38/attachment.htm From fredrik at pythonware.com Wed Jul 9 15:02:10 2003 From: fredrik at pythonware.com (Fredrik Lundh) Date: Wed Jul 9 08:04:29 2003 Subject: [Image-SIG] Re: PIL installation References: <8F24A400BFCFD611AD3F00B0D0F9E9F1F8C9FE@MSG01NEL> Message-ID: PIL installation"DSIC SDEL NTIC2 DSIC SDEL" wrote: > I work for a french ministry and i would like to install PIL > under windows platform. I downloaded PIL version 1.1.4 > for Python 2.1. I launched file and there is nothing install. is the list of available Python installations empty? if so, this might help: http://effbot.org/zone/python-register.htm From fredrik at pythonware.com Wed Jul 9 15:06:21 2003 From: fredrik at pythonware.com (Fredrik Lundh) Date: Wed Jul 9 08:11:44 2003 Subject: [Image-SIG] Re: decoder jpeg not available References: <3F0B6B30.2050400@jaydorsey.com> Message-ID: Jay Dorsey wrote: > I could really use some assitance in troubleshooting this problem. I'm > using Python 2.3a, PIL 1.1.4 on Solaris 8. I installed the jpeg > libraries into the default locations (had to compile with > --enable-shared and --enable-static - that threw me off for about an > hour -- I'm not a Solaris guy). make test worked fine. I followed the > install instructions in the README file, and used the -fpic flag when > compiling in libImaging. I've followed the instructions on > http://effbot.org/zone/pil-decoder-jpeg-not-available.htm (twice), with > no luck (Excellent instructions/documentation however). I do receive > the "checking for jpeg_destroy_compress in _ljpeg... no" message. that's expected behaviour (see item #1). have you checked the contents of the JpegDecode.o/JpegEncode.o files? (see item #4) From jay at jaydorsey.com Wed Jul 9 09:44:32 2003 From: jay at jaydorsey.com (Jay Dorsey) Date: Wed Jul 9 08:44:04 2003 Subject: [Image-SIG] Re: decoder jpeg not available In-Reply-To: References: <3F0B6B30.2050400@jaydorsey.com> Message-ID: <3F0C0E30.1010303@jaydorsey.com> Fredrik Lundh wrote: > that's expected behaviour (see item #1). > > have you checked the contents of the JpegDecode.o/JpegEncode.o > files? (see item #4) > > > Yes. The Dib.o file is 492k, JpegDecode.o is 3200k, JpegEncode.o is 2632k. ZipDecode.o is 2344k, ZipEncode.o is 3280k. I compared these to the sizes on my hosted account (Red Hat, Python 2.2.2), and the file sizes are different (same version of PIL though). Any suggestions? Jay From python at jaydorsey.com Wed Jul 9 12:45:40 2003 From: python at jaydorsey.com (Jay Dorsey) Date: Wed Jul 9 11:45:13 2003 Subject: [Image-SIG] import _imaging fails in CGI Message-ID: <3F0C38A4.6000108@jaydorsey.com> I'm on Solaris 8, netscape server, Python 2.3a1. I finally got PIL 1.1.4 installed this morning. I can run everything just fine from the command line. When I try a regular import Image in the CGI script, it imports ok (I assume), but I get the "ImportError: The _imaging C module is not installed" error. I checked the effbot site again (too much useful information there -- where does he find the time?), http://effbot.org/zone/pil-imaging-not-installed.htm. I do have an _imaging module, located in /usr/local/lib/python2.3/site-packages/PIL. Doing an "import _imaging" from CLI, gives me: dlopen("/usr/local/lib/python2.3/site-packages/PIL/_imaging.so", 2); import _imaging # dynamically loaded from /usr/local/lib/python2.3/site-packages/PIL/_imaging.so When I do an "import _imaging" in my CGI script, I get the following: ImportError: ld.so.1: /usr/local/bin/python: fatal: libjpeg.so.62: open failed: No such file or directory I printed out my sys.path, and os.environ. My sys.path is correct, it points to the PIL directory (among others). os.environ doesn't show a LD_LIBRARY_PATH, but I set one (/usr/local/lib) before I import the _imaging module (also, I tried before Image). I checked for a libjpeg.so.62 file to make sure I had one -- I do. Its located in /usr/local/lib/. Its a symlink to /usr/local/lib/libjpeg.so.62.0.0 however. So, I tried re-compiling PIL with --with-jpeg=/usr/local/lib/libjpeg.so.62.0.0, but couldn't get PIL to compile using this method (I'm not sure that it even *should* work). I also checked the server, and it has a LD_LIBRARY_PATH of /usr/local/lib set upon start as well. Running 'ldd _imaging.so' shows me the link 'libjpeg.so.62 => /usr/local/lib/libjpeg.so.62' (among others). I found a newsgroup post on google suggesting 1. to recompile PIL to statically link to libjpeg , 2. recompile with -R so PIL remembers where the dynamic libs are, or 3. modify the server start script to set the enviroment variable. I don't think its a coincidence that the original poster was on a solaris machine either. 3 doesn't work (its already set), and I'm not sure exactly where/how to do 1 or 2 (though I'm snooping through all the make files and configure scripts). Unfortunately, there was no real closure on the matter, so I'm not sure what the original poster did. Any suggestions? THanks for your time. Jay From dougz at cs.washington.edu Thu Jul 10 09:50:27 2003 From: dougz at cs.washington.edu (Douglas Zongker) Date: Thu Jul 10 11:50:32 2003 Subject: [Image-SIG] obtaining palette data Message-ID: <20030710084755.K11530-100000@narino.cs.washington.edu> Is there an 'official' way to get the palette data from an Image? The way I was doing it with 1.1.3 (im.palette.data) no longer works in 1.1.4 (which seems to want im.palette.getdata()[1]); if there's a supported way of doing it that works across versions I'd like to know about it. thanks, dz From cbass233 at yahoo.com Thu Jul 10 13:29:54 2003 From: cbass233 at yahoo.com (Chuck Bass) Date: Thu Jul 10 15:30:00 2003 Subject: [Image-SIG] Obtaining image data in numarray In-Reply-To: Message-ID: <20030710192954.62838.qmail@web13901.mail.yahoo.com> I need to look at the image data in an array form (ideally using numarray). With PIL I could loop over the data and stuff x,y's into a numarray but the speed would be glacial large images. It looks like PythonMagick has a direct way to get to numpy arrays but not numarrays. Any idea's or pointers. I could tackle the C coding to make this work assuming that the DOD of linking with PIL code and Numarray isn't too esoteric. Chuck Bass Metron Systems __________________________________ Do you Yahoo!? SBC Yahoo! DSL - Now only $29.95 per month! http://sbc.yahoo.com From jay at jaydorsey.com Fri Jul 11 10:09:16 2003 From: jay at jaydorsey.com (Jay Dorsey) Date: Fri Jul 11 09:08:50 2003 Subject: [Image-SIG] import _imaging fails in CGI In-Reply-To: <3F0C38A4.6000108@jaydorsey.com> References: <3F0C38A4.6000108@jaydorsey.com> Message-ID: <3F0EB6FC.2010902@jaydorsey.com> Jay Dorsey wrote: > Any suggestions? I finally got it yesterday. The LD_LIBRARY_PATH was being set in the Netscape HTTP Server (not sure which version, sorry), but that wasn't enough. Even setting the LD_LIBRARY_PATH in the script didn't work. However, I did some more snooping around on google and I putting the following line in my obj.conf file works: Init fn="init-cgi" LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/lib/" Works like a champ now :) Jay From jbreiden at parc.com Fri Jul 11 10:49:33 2003 From: jbreiden at parc.com (Jeff Breidenbach) Date: Fri Jul 11 12:49:49 2003 Subject: [Image-SIG] Obtaining image data in numarray (Chuck Bass) In-Reply-To: References: Message-ID: <1057942172.12079.2.camel@rode> > I need to look at the image data in an array form (ideally using > numarray). With PIL I could loop over the data and stuff x,y's into a > numarray but the speed would be glacial large images. http://effbot.org/zone/pil-numpy.htm -- Jeff Breidenbach Member of Research Staff, PARC Life is too short to be profound From cbass233 at yahoo.com Fri Jul 11 13:31:31 2003 From: cbass233 at yahoo.com (Chuck Bass) Date: Fri Jul 11 15:31:34 2003 Subject: [Image-SIG] Re: Obtaining image data in numarray In-Reply-To: Message-ID: <20030711193131.96228.qmail@web13901.mail.yahoo.com> After doing more searching I was able to find a reference to PIL in numarray docs and found that both numarray and PIL support to/fromstring methods. With these methods I was able to convert images into numarrays and back using grayscale and RGB images (no luck with monochrome images yet,it appears that there are a few bits left over when data isn't a multiple of 8). Chuck > > I need to look at the image data in an array form (ideally using > numarray). With PIL I could loop over the data and stuff x,y's into > a > numarray but the speed would be glacial large images. > > It looks like PythonMagick has a direct way to get to numpy arrays > but > not numarrays. > > Any idea's or pointers. I could tackle the C coding to make this > work > assuming that the DOD of linking with PIL code and Numarray isn't too > esoteric. > > Chuck Bass > Metron Systems > > __________________________________ > Do you Yahoo!? > SBC Yahoo! DSL - Now only $29.95 per month! > http://sbc.yahoo.com > > __________________________________ Do you Yahoo!? SBC Yahoo! DSL - Now only $29.95 per month! http://sbc.yahoo.com From alan.grosskurth at utoronto.ca Sun Jul 13 21:55:50 2003 From: alan.grosskurth at utoronto.ca (Alan Grosskurth) Date: Sun Jul 13 16:55:51 2003 Subject: [Image-SIG] Image.eval problem with math.sqrt Message-ID: <20030713205546.GA851@seawolf.cdf.toronto.edu> Hello, I'm trying to apply a square root transformation to an image: in = Image.open('lena.jpeg') out = Image.eval(math.sqrt, in) As far as I can see, this should work because math.sqrt is a function that takes one argument. But I get the following error: File "/h/45/grosskur/lib/python2.2/site-packages/PIL/Image.py", line 1634, in eval return image.point(args[0]) AttributeError: 'builtin_function_or_method' object has no attribute 'point' Any help is appreciated. Thanks, Alan -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://mail.python.org/pipermail/image-sig/attachments/20030713/fcdc9d22/attachment.bin From wmcclain at salamander.com Sun Jul 13 18:07:37 2003 From: wmcclain at salamander.com (wmcclain@salamander.com) Date: Sun Jul 13 18:05:41 2003 Subject: [Image-SIG] Image.eval problem with math.sqrt In-Reply-To: <20030713205546.GA851@seawolf.cdf.toronto.edu> References: <20030713205546.GA851@seawolf.cdf.toronto.edu> Message-ID: <20030713170737.4cf5a625.wmcclain@salamander.com> On 13 Jul 2003 16:55:46 -0400 "Alan Grosskurth" wrote: > out = Image.eval(math.sqrt, in) > > As far as I can see, this should work because math.sqrt is a function > that takes one argument. But I get the following error: It looks like the arguments in the documentation are reversed. Should be: out = Image.eval(im, math.sqrt) (BTW: "in" is a reserved word). -Bill -- Sattre Press In the Quarter http://sattre-press.com/ by Robert W. Chambers info@sattre-press.com http://itq.sattre-press.com/ From alan.grosskurth at utoronto.ca Mon Jul 14 01:10:21 2003 From: alan.grosskurth at utoronto.ca (Alan Grosskurth) Date: Sun Jul 13 20:10:22 2003 Subject: [Image-SIG] Re: Image.eval problem with math.sqrt Message-ID: <20030714001017.GA16267@seawolf.cdf.toronto.edu> > It looks like the arguments in the documentation are reversed. Should > be: > > out = Image.eval(im, math.sqrt) Thanks for the help, Bill. That works fine for 8-bit images, but I'm still have trouble with mode 'I' images (32-bit integer): image = Image.new('I', (10, 10)) out = Image.eval(image, math.sqrt) And I get this error: Traceback (most recent call last): File "", line 1, in ? File "/h/45/grosskur/lib/python2.2/site-packages/PIL/Image.py", line 1634, in eval return image.point(args[0]) File "/h/45/grosskur/lib/python2.2/site-packages/PIL/Image.py", line 924, in point scale, offset = _getscaleoffset(lut) File "/h/45/grosskur/lib/python2.2/site-packages/PIL/Image.py", line 339, in _getscaleoffset data = expr(_E(stub)).data AttributeError: _E instance has no attribute '__float__' Any help is appreciated. Thanks, Alan From wmcclain at salamander.com Mon Jul 14 07:46:38 2003 From: wmcclain at salamander.com (wmcclain@salamander.com) Date: Mon Jul 14 07:44:38 2003 Subject: [Image-SIG] Re: Image.eval problem with math.sqrt In-Reply-To: <20030714001017.GA16267@seawolf.cdf.toronto.edu> References: <20030714001017.GA16267@seawolf.cdf.toronto.edu> Message-ID: <20030714064638.5c981e9b.wmcclain@salamander.com> On 13 Jul 2003 20:10:17 -0400 "Alan Grosskurth" wrote: > That works fine for 8-bit images, but I'm > still have trouble with mode 'I' images (32-bit integer): > > image = Image.new('I', (10, 10)) > out = Image.eval(image, math.sqrt) This gets beyond my knowledge. That code calls point(), and according to the docs: If the image has mode "I" (integer) or "F" (floating point), you must use a function, and it must have the following format: argument * scale+ offset Example: Map floating point images out = im.point(lambda i: i * 1.2 + 10) You can leave out either the scale or the offset. Using the example lambda works in your eval(), but I don't see how to get in a sqrt(). Perhaps someone with better Python knowledge can help? -Bill -- Sattre Press The King in Yellow http://sattre-press.com/ by Robert W. Chambers info@sattre-press.com http://kiy.sattre-press.com/ From andrew.straw at adelaide.edu.au Mon Jul 14 16:09:04 2003 From: andrew.straw at adelaide.edu.au (Andrew Straw) Date: Mon Jul 14 09:08:44 2003 Subject: [Image-SIG] Obtaining image data in numarray In-Reply-To: <20030710192954.62838.qmail@web13901.mail.yahoo.com> Message-ID: <57EFB7D8-B5FC-11D7-9F89-00039311EA24@adelaide.edu.au> On Thursday, July 10, 2003, at 09:29 PM, Chuck Bass wrote: > I need to look at the image data in an array form (ideally using > numarray). With PIL I could loop over the data and stuff x,y's into a > numarray but the speed would be glacial large images. I'm not the expert, but seeing as no one better qualified has answered: I don't think C coding is needed, even for decent speed. Here's Python code for Numeric, and I assume there must be something extremely similar for numarray. There are also a number of similar recipes floating around. import Numeric import Image def pil2numpy(im): if im.mode != 'RGB': raise ValueError("Expecting RGB image") width, height = im.size im_n = Numeric.fromstring( im.tostring('raw','RGB',0,-1), Numeric.UnsignedInt8 ) im_n = Numeric.reshape( im_n, (height,width,3) ) return im_n From bartek at rezolwenta.eu.org Mon Jul 14 20:35:23 2003 From: bartek at rezolwenta.eu.org (Bartek Wilczynski) Date: Mon Jul 14 13:34:45 2003 Subject: [Image-SIG] Re: Image.eval problem with math.sqrt Message-ID: <1058204122.3f12e9db03982@imp.rezolwenta.eu.org> This is probably much slower than the point (or eval) operation, but it works. >>> image = Image.new('I', (10, 10)) >>> img = Image.eval(image, math.sqrt) >>> for x in xrange(img.size[0]): ... for y in xrange(img.size[1]): ... img.putpixel((x,y),math.sqrt(image.getpixel((x,y)))) ... BTW I'm wondering what's the reason for this special form lambda in the point operator Hope that helps. -- regards Bartek Wilczy?ski Quoting wmcclain@salamander.com: > On 13 Jul 2003 20:10:17 -0400 > "Alan Grosskurth" wrote: > > > That works fine for 8-bit images, but I'm > > still have trouble with mode 'I' images (32-bit integer): > > > > image = Image.new('I', (10, 10)) > > out = Image.eval(image, math.sqrt) > > This gets beyond my knowledge. That code calls point(), and according to > the docs: > > If the image has mode "I" (integer) or "F" (floating point), you > must use a function, and it must have the following format: argument > * scale+ offset > > Example: Map floating point images > > out = im.point(lambda i: i * 1.2 + 10) > > You can leave out either the scale or the offset. > > Using the example lambda works in your eval(), but I don't see how to > get in a sqrt(). Perhaps someone with better Python knowledge can help? > > -Bill > -- > Sattre Press The King in Yellow > http://sattre-press.com/ by Robert W. Chambers > info@sattre-press.com http://kiy.sattre-press.com/ > From mileruiz at hotmail.com Wed Jul 23 11:35:46 2003 From: mileruiz at hotmail.com (sandra ruiz) Date: Wed Jul 23 11:46:04 2003 Subject: [Image-SIG] IOError: cannot find glyph data file Message-ID: hi list, I'm a newbie user of PIL When I try to load a font to draw text I get this error: font = ImageFont.load ('courB08.pil') Traceback (most recent call last): File "", line 1, in ? File "/usr/lib/python2.2/site-packages/PIL/ImageFont.py", line 168, in load f._load_pilfont(filename) File "/usr/lib/python2.2/site-packages/PIL/ImageFont.py", line 78, in _load_pilfont raise IOError("cannot find glyph data file") I dont know what is a 'glyph data file'..I dont know where to start.. I'm using Imaging-1.1.4 thanks. _________________________________________________________________ Charla con tus amigos en l?nea mediante MSN Messenger: http://messenger.yupimsn.com/ From jbreiden at parc.com Wed Jul 23 11:03:27 2003 From: jbreiden at parc.com (Jeff Breidenbach) Date: Wed Jul 23 13:03:45 2003 Subject: [Image-SIG] IOError: cannot find glyph data file (sandra ruiz)> In-Reply-To: References: Message-ID: <1058979807.14536.2.camel@rode> It's the .pbm file; put it in the same directory as the .pil file. More details here: http://www.cis.upenn.edu/~edloper/programs/tree2image/install.html > hi list, > > I'm a newbie user of PIL When I try to load a font to draw text I get this > error: > > font = ImageFont.load ('courB08.pil') > Traceback (most recent call last): > File "", line 1, in ? > File "/usr/lib/python2.2/site-packages/PIL/ImageFont.py", line 168, in > load > f._load_pilfont(filename) > File "/usr/lib/python2.2/site-packages/PIL/ImageFont.py", line 78, in > _load_pilfont > raise IOError("cannot find glyph data file") > > I dont know what is a 'glyph data file'..I dont know where to start.. > > I'm using Imaging-1.1.4 > > thanks. > > _________________________________________________________________ > Charla con tus amigos en l?nea mediante MSN Messenger: > http://messenger.yupimsn.com/ -- Jeff Breidenbach Member of Research Staff, PARC Life is too short to be profound From vpastukhov at naumen.ru Tue Jul 29 22:32:07 2003 From: vpastukhov at naumen.ru (Vladimir Pastukhov) Date: Tue Jul 29 11:32:14 2003 Subject: [Image-SIG] PATCH: Group 4 TIFF compression support Message-ID: <3F269377.10009@naumen.ru> Hello, Enclosed patch for PIL 1.1.4 enables reading files encoded with group3, group4, tiff_ccitt and tiff_raw_16 TIFF compression schemes. Internally it uses libtiff (www.libtiff.org) for decompression. The following additional steps are required to build PIL with libtiff: 1. Install libtiff library version 3.5.7. 2. For PIL compilation you will need a full set of libtiff include files, whereas only a subset of them gets installed. Get the libtiff source and run configure to prepare headers in libtiff subdirectory. 3. Adjust paths to libtiff header files and library in setup.py and libImaging/Makefile. 4. Define HAVE_LIBTIFF in libImaging/ImConfig.h The code has been tested so far only with a limited set of group4-encoded images. Feedback and bug reports are welcome. Best regards, -- Vladimir Pastukhov -------------- next part -------------- --- ./PIL/TiffImagePlugin.py.orig Wed May 7 02:44:17 2003 +++ ./PIL/TiffImagePlugin.py Tue Jul 29 18:35:36 2003 @@ -65,6 +65,7 @@ BITSPERSAMPLE = 258 COMPRESSION = 259 PHOTOMETRIC_INTERPRETATION = 262 +FILLORDER = 266 IMAGEDESCRIPTION = 270 STRIPOFFSETS = 273 SAMPLESPERPIXEL = 277 @@ -451,7 +452,7 @@ return self.__frame - def _decoder(self, rawmode, layer): + def _decoder(self, rawmode, layer, tile=None): "Setup decoder contexts" args = None @@ -459,6 +460,13 @@ rawmode = rawmode[layer] if self._compression == "raw": args = (rawmode, 0, 1) + if self._compression in ["tiff_ccitt", "group3", "group4", "tiff_raw_16"]: + args = (rawmode, + self._compression, + (self.tag.has_key(FILLORDER)) \ + and self.tag[FILLORDER][0] or -1, + (tile is not None and self.tag.has_key(STRIPBYTECOUNTS)) \ + and self.tag[STRIPBYTECOUNTS][tile] or -1) if self._compression in ["packbits", "tiff_lzw", "jpeg"]: args = rawmode if self._compression == "jpeg" and self.tag.has_key(JPEGTABLES): @@ -525,16 +533,15 @@ self.tile = [] if self.tag.has_key(STRIPOFFSETS): # striped image + offsets = self.tag[STRIPOFFSETS] h = getscalar(ROWSPERSTRIP, ysize) w = self.size[0] - a = None - for o in self.tag[STRIPOFFSETS]: - if not a: - a = self._decoder(rawmode, l) + for i in range(len(offsets)): + a = self._decoder(rawmode, l, i) self.tile.append( (self._compression, (0, min(y, ysize), w, min(y+h, ysize)), - o, a)) + offsets[i], a)) y = y + h if y >= self.size[1]: x = y = 0 --- ./Setup.in.orig Tue Apr 22 22:11:25 2003 +++ ./Setup.in Fri Jul 25 16:18:52 2003 @@ -32,6 +32,9 @@ # *** IJG JPEG library (libjpeg) location -I/usr/local/include -L/usr/local/lib -ljpeg \ # +# *** TIFF library (libtiff) location + -I../../kits/tifflib -ltiff \ +# # *** ZLIB (libz) location -I/usr/local/include -L/usr/local/lib -lz --- ./_imaging.c.orig Sat Apr 26 17:50:24 2003 +++ ./_imaging.c Fri Jul 25 17:48:02 2003 @@ -2658,6 +2658,7 @@ extern PyObject* PyImaging_HexDecoderNew(PyObject* self, PyObject* args); extern PyObject* PyImaging_JpegDecoderNew(PyObject* self, PyObject* args); extern PyObject* PyImaging_TiffLzwDecoderNew(PyObject* self, PyObject* args); +extern PyObject* PyImaging_LibTiffDecoderNew(PyObject* self, PyObject* args); extern PyObject* PyImaging_MspDecoderNew(PyObject* self, PyObject* args); extern PyObject* PyImaging_PackbitsDecoderNew(PyObject* self, PyObject* args); extern PyObject* PyImaging_PcdDecoderNew(PyObject* self, PyObject* args); @@ -2719,6 +2720,12 @@ {"jpeg_encoder", (PyCFunction)PyImaging_JpegEncoderNew, 1}, #endif {"tiff_lzw_decoder", (PyCFunction)PyImaging_TiffLzwDecoderNew, 1}, +#ifdef HAVE_LIBTIFF + {"tiff_ccitt_decoder", (PyCFunction)PyImaging_LibTiffDecoderNew, 1}, + {"group3_decoder", (PyCFunction)PyImaging_LibTiffDecoderNew, 1}, + {"group4_decoder", (PyCFunction)PyImaging_LibTiffDecoderNew, 1}, + {"tiff_raw_16_decoder", (PyCFunction)PyImaging_LibTiffDecoderNew, 1}, +#endif {"msp_decoder", (PyCFunction)PyImaging_MspDecoderNew, 1}, {"packbits_decoder", (PyCFunction)PyImaging_PackbitsDecoderNew, 1}, {"pcd_decoder", (PyCFunction)PyImaging_PcdDecoderNew, 1}, --- ./decode.c.orig Tue Apr 22 22:11:26 2003 +++ ./decode.c Tue Jul 29 19:59:17 2003 @@ -52,6 +52,7 @@ PyObject_HEAD int (*decode)(Imaging im, ImagingCodecState state, UINT8* buffer, int bytes); + void (*cleanup)(ImagingCodecState state); struct ImagingCodecStateInstance state; Imaging im; PyObject* lock; @@ -87,6 +88,7 @@ /* Initialize decoder context */ decoder->state.context = context; + decoder->cleanup = NULL; /* Target image */ decoder->lock = NULL; @@ -98,6 +100,8 @@ static void _dealloc(ImagingDecoderObject* decoder) { + if (decoder->cleanup) + decoder->cleanup(&decoder->state); free(decoder->state.buffer); free(decoder->state.context); Py_XDECREF(decoder->lock); @@ -381,6 +385,80 @@ return (PyObject*) decoder; } +/* -------------------------------------------------------------------- */ +/* LibTiff */ +/* -------------------------------------------------------------------- */ + +#ifdef HAVE_LIBTIFF + +#include "Tiff.h" + +#include +#ifdef __WIN32__ +#define strcasecmp(s1, s2) stricmp(s1, s2) +#endif + +PyObject* +PyImaging_LibTiffDecoderNew(PyObject* self, PyObject* args) +{ + ImagingDecoderObject* decoder; + char* mode; + char* rawmode; + char* compname; + int compression; + int fillorder = -1; + int count = -1; + + if (! PyArg_ParseTuple(args, "sss|ii", &mode, &rawmode, &compname, &fillorder, &count)) + return NULL; + + TRACE(("new decoder %s, fillorder %d, %d bytes\n", compname, fillorder, count)); + + if (strcasecmp(compname, "tiff_ccitt") == 0) { + compression = COMPRESSION_CCITTRLE; + + } else if (strcasecmp(compname, "group3") == 0) { + compression = COMPRESSION_CCITTFAX3; + + } else if (strcasecmp(compname, "group4") == 0) { + compression = COMPRESSION_CCITTFAX4; + + } else if (strcasecmp(compname, "tiff_raw_16") == 0) { + compression = COMPRESSION_CCITTRLEW; + + } else { + PyErr_SetString(PyExc_ValueError, "unknown compession"); + return NULL; + } + + if (fillorder < 0) { + fillorder = FILLORDER_MSB2LSB; + + } else if (fillorder != FILLORDER_MSB2LSB && fillorder != FILLORDER_LSB2MSB) { + PyErr_SetString(PyExc_ValueError, "invalid fillorder"); + return NULL; + } + + decoder = PyImaging_DecoderNew(sizeof(TIFFSTATE)); + if (decoder == NULL) + return NULL; + + if (get_unpacker(decoder, mode, rawmode) < 0) + return NULL; + + if (! ImagingLibTiffInit(&decoder->state, compression, fillorder, count)) { + Py_DECREF(decoder); + PyErr_SetString(PyExc_RuntimeError, "tiff codec initialization failed"); + return NULL; + } + + decoder->decode = ImagingLibTiffDecode; + decoder->cleanup = ImagingLibTiffCleanup; + + return (PyObject*) decoder; +} + +#endif /* -------------------------------------------------------------------- */ /* MSP */ --- ./libImaging/ImConfig.h.in.orig Tue Apr 22 22:11:26 2003 +++ ./libImaging/ImConfig.h.in Fri Jul 25 15:12:29 2003 @@ -45,6 +45,9 @@ /* Define if you have the IJG jpeg library (-ljpeg). */ #undef HAVE_LIBJPEG +/* Define if you have the tiff library (-ltiff). */ +#undef HAVE_LIBTIFF + /* Define if you have the Greg Ward's mpeg library (-lmpeg). */ #undef HAVE_LIBMPEG --- ./libImaging/ImConfig.h.win.orig Tue Apr 22 22:11:26 2003 +++ ./libImaging/ImConfig.h.win Fri Jul 25 15:13:38 2003 @@ -13,6 +13,9 @@ /* Define if you have the IJG jpeg library (-ljpeg). */ #define HAVE_LIBJPEG +/* Define if you have the tiff library (-ltiff). */ +#define HAVE_LIBTIFF + /* Define if you have the Greg Ward's mpeg library (-lmpeg). */ #undef HAVE_LIBMPEG --- ./libImaging/Imaging.h.orig Tue Apr 22 22:56:24 2003 +++ ./libImaging/Imaging.h Fri Jul 25 15:29:59 2003 @@ -389,6 +389,10 @@ #endif extern int ImagingLzwDecode(Imaging im, ImagingCodecState state, UINT8* buffer, int bytes); +#ifdef HAVE_LIBTIFF +extern int ImagingLibTiffDecode(Imaging im, ImagingCodecState state, + UINT8* buffer, int bytes); +#endif #ifdef HAVE_LIBMPEG extern int ImagingMpegDecode(Imaging im, ImagingCodecState state, UINT8* buffer, int bytes); --- ./libImaging/Makefile.in.orig Tue Apr 22 22:11:26 2003 +++ ./libImaging/Makefile.in Fri Jul 25 16:18:22 2003 @@ -31,9 +31,10 @@ INCLDIR= $(srcdir)/. JPEGINCLUDE= /usr/local/include +TIFFINCLUDE= ../../../kits/tifflib OPT= @OPT@ #OPT= -g -CFLAGS= $(OPT) -I$(INCLDIR) -I$(JPEGINCLUDE) $(DEFS) +CFLAGS= $(OPT) -I$(INCLDIR) -I$(JPEGINCLUDE) -I$(TIFFINCLUDE) $(DEFS) MKDEP= mkdep SHELL= /bin/sh @@ -71,6 +72,7 @@ RawDecode.o RawEncode.o \ SunRleDecode.o \ TgaRleDecode.o \ + TiffDecode.o \ XbmDecode.o XbmEncode.o \ ZipDecode.o ZipEncode.o --- ./libImaging/Makefile.win.orig Tue Apr 22 22:11:26 2003 +++ ./libImaging/Makefile.win Thu Jul 24 22:19:22 2003 @@ -76,6 +76,7 @@ Storage.obj\ SunRleDecode.obj\ TgaRleDecode.obj\ + TiffDecode.obj\ Unpack.obj\ UnpackYCC.obj\ XbmDecode.obj\ --- ./libImaging/Tiff.h.orig Fri Jul 25 15:30:53 2003 +++ ./libImaging/Tiff.h Tue Jul 29 19:06:40 2003 @@ -0,0 +1,27 @@ +/* + * The Python Imaging Library. + * $Id: //modules/pil/libImaging/Tiff.h#1 $ + * + * declarations for the LibTiff-based Group3 and Group4 decoder + * + */ + +#include + +typedef struct { + + /* PRIVATE CONTEXT (set by decoder) */ + TIFF tiff; + int count; + +} TIFFSTATE; + +extern int ImagingLibTiffInit(ImagingCodecState state, int compression, int fillorder, int count); +extern void ImagingLibTiffCleanup(ImagingCodecState state); + +/* +#define VA_ARGS(...) __VA_ARGS__ +#define TRACE(args) fprintf(stderr, VA_ARGS args) +*/ + +#define TRACE(args) --- ./libImaging/TiffDecode.c.orig Fri Jul 25 15:30:58 2003 +++ ./libImaging/TiffDecode.c Tue Jul 29 19:06:48 2003 @@ -0,0 +1,185 @@ +/* + * The Python Imaging Library. + * $Id: //modules/pil/libImaging/TiffDecode.c#1 $ + * + * LibTiff-based Group3 and Group4 decoder + * + */ + +#include "Imaging.h" + +#ifdef HAVE_LIBTIFF + +#undef INT32 +#undef UINT32 + +#include "Tiff.h" + +#include + +#include +#include + +extern void _TIFFSetDefaultCompressionState(TIFF* tif); + +typedef void (*TIFFFaxFillFunc)(unsigned char*, uint32*, uint32*, uint32); + +typedef struct { + int rw_mode; /* O_RDONLY for decode, else encode */ + int mode; /* operating mode */ + uint32 rowbytes; /* bytes in a decoded scanline */ + uint32 rowpixels; /* pixels in a scanline */ + + uint16 cleanfaxdata; /* CleanFaxData tag */ + uint32 badfaxrun; /* BadFaxRun tag */ + uint32 badfaxlines; /* BadFaxLines tag */ + uint32 groupoptions; /* Group 3/4 options tag */ + uint32 recvparams; /* encoded Class 2 session params */ + char* subaddress; /* subaddress string */ + uint32 recvtime; /* time spent receiving (secs) */ + TIFFVGetMethod vgetparent; /* super-class method */ + TIFFVSetMethod vsetparent; /* super-class method */ +} Fax3BaseState; + +typedef struct { + Fax3BaseState b; + const u_char* bitmap; /* bit reversal table */ + uint32 data; /* current i/o byte/word */ + int bit; /* current i/o bit in byte */ + int EOLcnt; /* count of EOL codes recognized */ + TIFFFaxFillFunc fill; /* fill routine */ + uint32* runs; /* b&w runs for current/previous row */ + uint32* refruns; /* runs for reference line */ + uint32* curruns; /* runs for current line */ +} Fax3DecodeState; + + +#define DECODER_STATE(tiff) (UINT8 *)(tiff->tif_data + offsetof(Fax3DecodeState, bitmap)) +#define DECODER_STATE_SIZE (sizeof(Fax3DecodeState) - offsetof(Fax3DecodeState, bitmap)) + + +static void +_errorHandler(const char* module, const char* fmt, va_list ap) +{ + /* be quiet */ +} + +static void +_cleanupLibTiff( TIFF *tiff ) +{ + if (tiff->tif_cleanup) + tiff->tif_cleanup(tiff); + + if (tiff->tif_fieldinfo) + free(tiff->tif_fieldinfo); +} + +int +ImagingLibTiffInit(ImagingCodecState state, int compression, int fillorder, int count) +{ + TIFF *tiff = &((TIFFSTATE *) state->context)->tiff; + const TIFFCodec *codec; + + TIFFSetErrorHandler(_errorHandler); + TIFFSetWarningHandler(_errorHandler); + + codec = TIFFFindCODEC((uint16) compression); + if (codec == NULL) + return 0; + + _TIFFmemset(tiff, 0, sizeof (*tiff)); + _TIFFSetDefaultCompressionState(tiff); + TIFFDefaultDirectory(tiff); + + tiff->tif_mode = O_RDONLY; + tiff->tif_dir.td_fillorder = (uint16) fillorder; + tiff->tif_dir.td_compression = (uint16) compression; + + ((TIFFSTATE *) state->context)->count = count; + + if (! codec->init(tiff, 0)) { + _cleanupLibTiff(tiff); + return 0; + } + + return 1; +} + +void +ImagingLibTiffCleanup(ImagingCodecState state) +{ + _cleanupLibTiff( &((TIFFSTATE *) state->context)->tiff ); +} + +int +ImagingLibTiffDecode(Imaging im, ImagingCodecState state, UINT8* buffer, int bytes) +{ + TIFF *tiff = &((TIFFSTATE *) state->context)->tiff; + int count = ((TIFFSTATE *) state->context)->count; + int savecc; + UINT8 saveds[DECODER_STATE_SIZE]; + + if (bytes < count) + return 0; + + if ((tiff->tif_flags & TIFF_CODERSETUP) == 0) { + tiff->tif_dir.td_bitspersample = 1; + tiff->tif_dir.td_imagewidth = state->xsize; + tiff->tif_scanlinesize = TIFFScanlineSize(tiff); + + if (! tiff->tif_setupdecode(tiff) || ! tiff->tif_predecode(tiff, 0)) { + state->errcode = IMAGING_CODEC_BROKEN; + return -1; + } + + tiff->tif_flags |= TIFF_CODERSETUP; + } + + tiff->tif_row = state->y + state->yoff; + tiff->tif_rawcp = buffer; + tiff->tif_rawcc = bytes; + + TRACE(("decoding %d bytes, row %d\n", bytes, tiff->tif_row)); + for (;;) { + if (count < 0) { + savecc = tiff->tif_rawcc; + memcpy(saveds, DECODER_STATE(tiff), DECODER_STATE_SIZE); + } + + if (tiff->tif_decoderow(tiff, (tidata_t) state->buffer, + tiff->tif_scanlinesize, 0) < 0) { + TRACE(("decode error, %d bytes left\n", tiff->tif_rawcc)); + if (count < 0) + break; + state->errcode = IMAGING_CODEC_BROKEN; + return -1; + } + + if (count < 0 && tiff->tif_rawcc <= 0) { + TRACE(("not enough data\n")); + break; + } + + tiff->tif_postdecode(tiff, (tidata_t) buffer, tiff->tif_scanlinesize); + + state->shuffle((UINT8*) im->image[state->y + state->yoff] + + state->xoff * im->pixelsize, state->buffer, + state->xsize); + + TRACE(("decoded row %d, %d bytes left\n", tiff->tif_row, tiff->tif_rawcc)); + tiff->tif_row++; + state->y++; + + if (state->y >= state->ysize) { + TRACE(("decoded %d rows\n", state->y)); + return -1; /* errcode = 0 */ + } + } + + memcpy(DECODER_STATE(tiff), saveds, DECODER_STATE_SIZE); + + TRACE(("decoded %d rows, %d bytes left\n", state->y, savecc)); + return bytes - savecc; +} + +#endif --- ./setup.py.orig Fri May 9 18:00:56 2003 +++ ./setup.py Fri Jul 25 16:18:34 2003 @@ -24,6 +24,7 @@ # on windows, the build script expects to find both library files and # include files in the directories below. tweak as necessary. JPEGDIR = "../../kits/jpeg-6b" +TIFFDIR = "../../kits/tifflib" ZLIBDIR = "../../kits/zlib-1.1.4" FREETYPEDIR = "../../kits/freetype-2.0" @@ -72,6 +73,8 @@ elif lib == "TIFF": HAVE_LIBTIFF = 1 LIBRARIES.append("tiff") + INCLUDE_DIRS.append(TIFFDIR) + LIBRARY_DIRS.append(TIFFDIR) elif lib == "Z": HAVE_LIBZ = 1 if sys.platform == "win32": From jbreiden at parc.com Tue Jul 29 10:29:04 2003 From: jbreiden at parc.com (Jeff Breidenbach) Date: Tue Jul 29 12:29:19 2003 Subject: [Image-SIG] PATCH: Group 4 TIFF compression support In-Reply-To: References: Message-ID: <1059496144.7300.3.camel@rode> Excellent! I'd be very happy if Group 4 TIFF support was incorporated into the next PIL release. > Enclosed patch for PIL 1.1.4 enables reading files encoded with > group3, group4, tiff_ccitt and tiff_raw_16 TIFF compression schemes. > Internally it uses libtiff (www.libtiff.org) for decompression. -- Jeff Breidenbach Member of Research Staff, PARC