message: Fix off-by-one grayscale JPEG encoding
  * Fix off-by-one grayscale JPEG encoding
  Closes PistonDevelopers/image#735.
  * Add regression test for gray JPEG encoding
  Note that the sanity check image must be larger than 1x1 because
  `value_at` wraps indexing, so the off-by-one index error would still
  reference the single pixel.
diff: @@ -663,7 +663,7 @@ fn copy_blocks_gray(source: &[u8],
  for x in 0usize..8 {
  let xstride = x0 * bpp + x * bpp;
  - gb[y * 8 + x] = value_at(source, ystride + xstride + 1);
  + gb[y * 8 + x] = value_at(source, ystride + xstride + 0);
  }
  }
  }
  @@ -708,4 +708,38 @@ mod tests {
  }
  }
  }
  +
  + #[test]
  + fn grayscale_roundtrip_sanity_check() {
  + // create a 2x2 8-bit image buffer containing a white diagonal
  + let img = [255u8, 0, 0, 255];
  +
  + // encode it into a memory buffer
  + let mut encoded_img = Vec::new();
  + {
  + let mut encoder =
  + JPEGEncoder::new_with_quality(&mut encoded_img, 100);
  + encoder.encode(&img, 2, 2, ColorType::Gray(8))
  + .expect("Could not encode image");
  + }
  +
  + // decode it from the memory buffer
  + {
  + let mut decoder =
  + JPEGDecoder::new(Cursor::new(&encoded_img));
  + match decoder.read_image().expect("Could not decode image") {
  + DecodingResult::U8(decoded) => {
  + // note that, even with the encode quality set to 100, we
  + // do not get the same image back. Therefore, we're going
  + // to assert that the diagonal is at least white-ish:
  + assert_eq!(4, decoded.len());
  + assert!(decoded[0] > 0x80);
  + assert!(decoded[1] < 0x80);
  + assert!(decoded[2] < 0x80);
  + assert!(decoded[3] > 0x80);
  + },
  + _ => panic!("Image did not decode as 8-bit"),
  + }
  + }
  + }
  }
  