diff -ur Imaging-1.1.6-orig/PIL/JpegImagePlugin.py Imaging-1.1.6/PIL/JpegImagePlugin.py --- Imaging-1.1.6-orig/PIL/JpegImagePlugin.py 2006-12-03 03:37:15.000000000 -0800 +++ Imaging-1.1.6/PIL/JpegImagePlugin.py 2008-01-30 08:48:28.707703071 -0800 @@ -403,7 +403,8 @@ info.get("smooth", 0), info.has_key("optimize"), info.get("streamtype", 0), - dpi[0], dpi[1] + dpi[0], dpi[1], + info.get("subsampling", -1) ) ImageFile._save(im, fp, [("jpeg", (0,0)+im.size, 0, rawmode)]) diff -ur Imaging-1.1.6-orig/encode.c Imaging-1.1.6/encode.c --- Imaging-1.1.6-orig/encode.c 2006-12-03 03:51:25.000000000 -0800 +++ Imaging-1.1.6/encode.c 2008-01-31 11:35:48.124779643 -0800 @@ -503,9 +503,10 @@ int optimize = 0; int streamtype = 0; /* 0=interchange, 1=tables only, 2=image only */ int xdpi = 0, ydpi = 0; - if (!PyArg_ParseTuple(args, "ss|iiiiiii", &mode, &rawmode, &quality, + int subsampling = -1; /* -1=default, 0=none, 1=medium, 2=high */ + if (!PyArg_ParseTuple(args, "ss|iiiiiiii", &mode, &rawmode, &quality, &progressive, &smooth, &optimize, &streamtype, - &xdpi, &ydpi)) + &xdpi, &ydpi, &subsampling)) return NULL; encoder = PyImaging_EncoderNew(sizeof(JPEGENCODERSTATE)); @@ -518,6 +519,7 @@ encoder->encode = ImagingJpegEncode; ((JPEGENCODERSTATE*)encoder->state.context)->quality = quality; + ((JPEGENCODERSTATE*)encoder->state.context)->subsampling = subsampling; ((JPEGENCODERSTATE*)encoder->state.context)->progressive = progressive; ((JPEGENCODERSTATE*)encoder->state.context)->smooth = smooth; ((JPEGENCODERSTATE*)encoder->state.context)->optimize = optimize; diff -ur Imaging-1.1.6-orig/libImaging/Jpeg.h Imaging-1.1.6/libImaging/Jpeg.h --- Imaging-1.1.6-orig/libImaging/Jpeg.h 2006-12-03 03:37:25.000000000 -0800 +++ Imaging-1.1.6/libImaging/Jpeg.h 2008-01-30 08:48:19.611543368 -0800 @@ -85,6 +85,9 @@ /* DPI setting (0=square pixels, otherwide DPI) */ int xdpi, ydpi; + /*Chroma Subsampling (-1=default, 0=none, 1=medium, 2=high) */ + int subsampling; + /* PRIVATE CONTEXT (set by encoder) */ struct jpeg_compress_struct cinfo; diff -ur Imaging-1.1.6-orig/libImaging/JpegEncode.c Imaging-1.1.6/libImaging/JpegEncode.c --- Imaging-1.1.6-orig/libImaging/JpegEncode.c 2006-12-03 03:37:25.000000000 -0800 +++ Imaging-1.1.6/libImaging/JpegEncode.c 2008-01-31 11:39:40.763673088 -0800 @@ -143,6 +143,46 @@ jpeg_set_defaults(&context->cinfo); if (context->quality > 0) jpeg_set_quality(&context->cinfo, context->quality, 1); + + /* Set subsampling options */ + switch (context->subsampling) + { + case 0: /* 1x1 1x1 1x1 (4:4:4) : None */ + { + context->cinfo.comp_info[0].h_samp_factor = 1; + context->cinfo.comp_info[0].v_samp_factor = 1; + context->cinfo.comp_info[1].h_samp_factor = 1; + context->cinfo.comp_info[1].v_samp_factor = 1; + context->cinfo.comp_info[2].h_samp_factor = 1; + context->cinfo.comp_info[2].v_samp_factor = 1; + break; + } + case 1: /* 2x1, 1x1, 1x1 (4:2:2) : Medium */ + { + context->cinfo.comp_info[0].h_samp_factor = 2; + context->cinfo.comp_info[0].v_samp_factor = 1; + context->cinfo.comp_info[1].h_samp_factor = 1; + context->cinfo.comp_info[1].v_samp_factor = 1; + context->cinfo.comp_info[2].h_samp_factor = 1; + context->cinfo.comp_info[2].v_samp_factor = 1; + break; + } + case 2: /* 2x2, 1x1, 1x1 (4:1:1) : High */ + { + context->cinfo.comp_info[0].h_samp_factor = 2; + context->cinfo.comp_info[0].v_samp_factor = 2; + context->cinfo.comp_info[1].h_samp_factor = 1; + context->cinfo.comp_info[1].v_samp_factor = 1; + context->cinfo.comp_info[2].h_samp_factor = 1; + context->cinfo.comp_info[2].v_samp_factor = 1; + break; + } + default: + { + /* Use the lib's default */ + break; + } + } if (context->progressive) jpeg_simple_progression(&context->cinfo); context->cinfo.smoothing_factor = context->smooth;