On Fri, Dec 12, 2008 at 17:55, Kevin Cazabon <[email protected]> wrote:
> A couple years ago, a few of us worked on adding multi-threading support to
> key routines in PIL - focusing on the ones that would most likely be CPU
> intensive or long duration operations. It's a simple fix to release the GIL
> before starting the op, and re-acquire before returning - look at the C code
> for resize, for example. We didn't get it implemented everywhere, but many
> of the "expensive" operations are now covered. I'm sure Fred would gladly
> accept patches to add support elsewhere.
>
> Kevin.
Hi Kevin, thanks for the quick reply. I've followed your advice and it
was simpler then I thought. I've attached two patches to this email.
One diff is your old patch I was using to correctly convert CMYK
images to RGB. The other one drops the GIL when saving png images.
Could these be committed to the PIL svn repo after a review?
Thanks,
Michael
>
> On 12 Dec 2008, at 11:34, Michael van Tellingen wrote:
>
>> Hello,
>>
>> I'm currently writing a webapplication which processes images uploaded
>> by users and i'm running into two problems:
>> - Converting a CMYK jpeg image to RGB results in the wrong colors
>> used, i've solved this by patching PIL with the
>> file attached to
>> http://mail.python.org/pipermail/image-sig/2006-April/003871.html
>>
>> - It seems that writing a PNG image requires the GIL. I convert all
>> uploaded images in a separate thread to PNG
>> images and while doing so my complete python application becomes
>> really slow, I don't have this problem when
>> I convert it to JPEG or TIFF. Is this correct? And if so, how hard
>> would it be to solve this problem?
>>
>> Thanks,
>> Michael van Tellingen
>> _______________________________________________
>> Image-SIG maillist - [email protected]
>> http://mail.python.org/mailman/listinfo/image-sig
>
>
Index: PIL/JpegImagePlugin.py
===================================================================
--- PIL/JpegImagePlugin.py (revision 460)
+++ PIL/JpegImagePlugin.py (working copy)
@@ -1,6 +1,6 @@
#
# The Python Imaging Library.
-# $Id: JpegImagePlugin.py 2763 2006-06-22 21:43:28Z fredrik $
+# $Id: JpegImagePlugin.py 2199 2004-12-18 08:49:05Z fredrik $
#
# JPEG (JFIF) file handling
#
@@ -32,7 +32,7 @@
__version__ = "0.5"
import array, string
-import Image, ImageFile
+import Image, ImageFile, ImageChops
def i16(c,o=0):
return ord(c[o+1]) + (ord(c[o])<<8)
@@ -270,8 +270,11 @@
handler(self, i)
if i == 0xFFDA: # start of scan
rawmode = self.mode
- if self.mode == "CMYK":
- rawmode = "CMYK;I"
+ # patch by Kevin Cazabon to comment this out - nobody should be using Photoshop 2.5 any more (and it breaks newer versions)
+ # CMYK images are still inverted, we'll fix that just before returning.
+ #if self.mode == "CMYK" and self.info.has_key("adobe"):
+ # rawmode = "CMYK;I" # Photoshop 2.5 is broken!
+
self.tile = [("jpeg", (0,0) + self.size, 0, (rawmode, ""))]
# self.__offset = self.fp.tell()
break
@@ -282,6 +285,10 @@
else:
raise SyntaxError("no marker found")
+ # patch by Kevin Cazabon to re-invert CMYK JPEG files
+ if self.mode == "CMYK":
+ self.im = ImageChops.invert(self).im
+
def draft(self, mode, size):
if len(self.tile) != 1:
@@ -378,7 +385,7 @@
"RGB": "RGB",
"RGBA": "RGB",
"RGBX": "RGB",
- "CMYK": "CMYK;I",
+ "CMYK": "CMYK",
"YCbCr": "YCbCr",
}
@@ -406,6 +413,10 @@
dpi[0], dpi[1]
)
+ if im.mode == "CMYK":
+ # invert it so it's handled correctly in Photoshop/etc. - Kevin Cazabon.
+ im = ImageChops.invert(im)
+
ImageFile._save(im, fp, [("jpeg", (0,0)+im.size, 0, rawmode)])
def _save_cjpeg(im, fp, filename):
Index: libImaging/ZipEncode.c
===================================================================
--- libImaging/ZipEncode.c (revision 460)
+++ libImaging/ZipEncode.c (working copy)
@@ -28,6 +28,7 @@
int err;
UINT8* ptr;
int i, bpp, s, sum;
+ ImagingSectionCookie cookie;
if (!state->state) {
@@ -104,6 +105,7 @@
context->z_stream.next_out = buf;
context->z_stream.avail_out = bytes;
+ ImagingSectionEnter(&cookie);
for (;;) {
switch (state->state) {
@@ -258,6 +260,7 @@
free(context->prior);
free(context->previous);
deflateEnd(&context->z_stream);
+ ImagingSectionEnter(&cookie);
return -1;
}
@@ -300,13 +303,13 @@
}
}
-
+ ImagingSectionLeave(&cookie);
return bytes - context->z_stream.avail_out;
}
/* Should never ever arrive here... */
-
+ ImagingSectionEnter(&cookie);
state->errcode = IMAGING_CODEC_CONFIG;
return -1;
}
_______________________________________________
Image-SIG maillist - [email protected]
http://mail.python.org/mailman/listinfo/image-sig