# Buggy code
def get_sampling(im):
    sampling = im.layer[0][1:3] + im.layer[1][1:3] + im.layer[2][1:3]
    return samplings.get(sampling, -1)


# Traceback (IndexError)
$ ipython
Python 2.7.6 (default, Apr  3 2014, 19:58:06)
Type "copyright", "credits" or "license" for more information.

IPython 2.1.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: import PIL

In [2]: PIL.PILLOW_VERSION,  PIL.VERSION
Out[2]: ('2.5.1', '1.1.7')

In [3]: from PIL import Image

In [4]: ll /tmp/72.jpg
-rw-r--r--  1 ywang  wheel  43990 Mar 13 12:37 /tmp/72.jpg

In [5]: im = Image.open('/tmp/72.jpg')

In [6]: im.layer
Out[6]: [('\x01', 1, 1, 0)]

In [7]: im
Out[7]: <PIL.JpegImagePlugin.JpegImageFile image mode=L size=600x339 at 0x10AE8F1B8>

In [8]: im.format
Out[8]: 'JPEG'

In [9]: im.save('/tmp/72-keep.jpg', 'JPEG', quality='keep')
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-9-dfd9f8d20942> in <module>()
----> 1 im.save('/tmp/72-keep.jpg', 'JPEG', quality='keep')

/Users/ywang/.envs/dbi/lib/python2.7/site-packages/PIL/Image.pyc in save(self, fp, format, **params)
1661
1662         try:
-> 1663             save_handler(self, fp, filename)
1664         finally:
1665             # do what we can to clean up

/Users/ywang/.envs/dbi/lib/python2.7/site-packages/PIL/JpegImagePlugin.pyc in _save(im, fp, filename)
512         if im.format != "JPEG":
513             raise ValueError("Cannot use 'keep' when original image is not a JPEG")
--> 514         subsampling = get_sampling(im)
515
516     def validate_qtables(qtables):

/Users/ywang/.envs/dbi/lib/python2.7/site-packages/PIL/JpegImagePlugin.pyc in get_sampling(im)
467
468 def get_sampling(im):
--> 469     sampling = im.layer[0][1:3] + im.layer[1][1:3] + im.layer[2][1:3]
470     return samplings.get(sampling, -1)
471

IndexError: list index out of range

In [10]: ll /tmp/72-keep.jpg
-rw-r--r--  1 ywang  wheel  0 Aug 19 12:18 /tmp/72-keep.jpg

In [11]: im.save('/tmp/72-q50.jpg', 'JPEG', quality=50)

In [12]: ll /tmp/72-q50.jpg
-rw-r--r--  1 ywang  wheel  33036 Aug 19 12:22 /tmp/72-q50.jpg

In [13]: im.save('/tmp/72-no-quality-specified.jpg', 'JPEG')

In [14]: ll /tmp/72-no-quality-specified.jpg
-rw-r--r--  1 ywang  wheel  45262 Aug 19 12:26 /tmp/72-no-quality-specified.jpg

In [15]: exit()

$ jhead /tmp/72*.jpg
Not JPEG: /tmp/72-keep.jpg
File name    : /tmp/72-no-quality-specified.jpg
File size    : 45262 bytes
File date    : 2014:08:19 12:26:26
Resolution   : 500 x 282
Color/bw     : Black and white
JPEG Quality : 75

File name    : /tmp/72-q50.jpg
File size    : 33036 bytes
File date    : 2014:08:19 12:22:28
Resolution   : 500 x 282
Color/bw     : Black and white
JPEG Quality : 50

File name    : /tmp/72.jpg
File size    : 43990 bytes
File date    : 2013:03:13 12:37:40
Resolution   : 600 x 339
Color/bw     : Black and white
JPEG Quality : 50

# Fixed code
def get_sampling(im):
    # There's no subsampling when image have only 1 layer
    # (grayscale images) or when they are CMYK (4 layers),
    # so set subsampling to default value.
    #
    # NOTE: currently Pillow can't encode JPEG to YCCK format.
    # If YCCK support is added in the future, subsampling code will have
    # to be updated (here and in JpegEncode.c) to deal with 4 layers.
    if not hasattr(im, "layers") or im.layers in (1, 4):
        return -1
    sampling = im.layer[0][1:3] + im.layer[1][1:3] + im.layer[2][1:3]
    return samplings.get(sampling, -1)