Page MenuHomePhabricator

Use Chroma subsampling for JPEG thumbs in VipsScaler
Open, MediumPublic

Description

Event Timeline

I think VIPS already does subsampling, but we have no control over which value it picks. We can just prevent it from doing subsampling via an option. Might be interesting to see what subsampling it picks right now. If it's like IM's default, it might depend on the quality setting.

Note that ImageMagick seems to be defaulting to whatever the source file had if nothing is specified.

Indeed, I was misled by old comment on the IM forums from 2011 which suggested that the behavior used to be different (i.e. IM would apply 4:2:0 to quality < 90, leave subsampling alone when quality >= 90).

I've done some quick tests and it does leave whatever it finds regardless of the quality setting.

From what I can tell, VIPS-generated images in production are 2x2,1x1,1x1 (4:2:2) now. Mark as complete?

@Jdforrester-WMF how can we distinguish between VIPS output and ImageMagick output? A fresh copy of https://upload.wikimedia.org/wikipedia/commons/thumb/c/ca/Salineras_de_Maras%2C_Maras%2C_Per%C3%BA%2C_2015-07-30%2C_DD_12.JPG/1594px-Salineras_de_Maras%2C_Maras%2C_Per%C3%BA%2C_2015-07-30%2C_DD_12.JPG looks to be correctly at 4:2:0 but it's also labeled as being produced by ImageMagick...

$ wget 'https://upload.wikimedia.org/wikipedia/commons/thumb/c/ca/Salineras_de_Maras%2C_Maras%2C_Per%C3%BA%2C_2015-07-30%2C_DD_12.JPG/1594px-Salineras_de_Maras%2C_Maras%2C_Per%C3%BA%2C_2015-07-30%2C_DD_12.JPG'
--2016-05-11 10:27:20--  https://upload.wikimedia.org/wikipedia/commons/thumb/c/ca/Salineras_de_Maras%2C_Maras%2C_Per%C3%BA%2C_2015-07-30%2C_DD_12.JPG/1594px-Salineras_de_Maras%2C_Maras%2C_Per%C3%BA%2C_2015-07-30%2C_DD_12.JPG
Resolving upload.wikimedia.org... 2620:0:860:ed1a::2:b, 208.80.153.240
Connecting to upload.wikimedia.org|2620:0:860:ed1a::2:b|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 575933 (562K) [image/jpeg]
Saving to: '1594px-Salineras_de_Maras,_Maras,_Per\303\272,_2015-07-30,_DD_12.JPG'

1594px-Salineras_de_Maras,_Maras,_Perú,_2 100%[=====================================================================================>] 562.43K  1.34MB/s    in 0.4s     

2016-05-11 10:27:35 (1.34 MB/s) - '1594px-Salineras_de_Maras,_Maras,_Per\303\272,_2015-07-30,_DD_12.JPG' saved [575933/575933]

Orac:hork brion$ id
id        identify  idle      idle2     idle2.6   idle2.7   idlj      
Orac:hork brion$ identify 1594px-Salineras_de_Maras,_Maras,_Perú,_2015-07-30,_DD_12.JPG 
1594px-Salineras_de_Maras,_Maras,_Perú,_2015-07-30,_DD_12.JPG JPEG 1594x1200 1594x1200+0+0 8-bit sRGB 576KB 0.000u 0:00.000
Orac:hork brion$ identify -verbose 1594px-Salineras_de_Maras,_Maras,_Perú,_2015-07-30,_DD_12.JPG 
Image: 1594px-Salineras_de_Maras,_Maras,_Perú,_2015-07-30,_DD_12.JPG
  Format: JPEG (Joint Photographic Experts Group JFIF format)
  Mime type: image/jpeg
  Class: DirectClass
  Geometry: 1594x1200+0+0
  Resolution: 300x300
  Print size: 5.31333x4
  Units: PixelsPerInch
  Type: TrueColor
  Endianess: Undefined
  Colorspace: sRGB
  Depth: 8-bit
  Channel depth:
    red: 8-bit
    green: 8-bit
    blue: 8-bit
  Channel statistics:
    Pixels: 1912800
    Red:
      min: 0 (0)
      max: 255 (1)
      mean: 152.379 (0.597566)
      standard deviation: 76.7527 (0.300991)
      kurtosis: -1.45812
      skewness: -0.314208
      entropy: 0.955034
    Green:
      min: 0 (0)
      max: 255 (1)
      mean: 153.447 (0.601754)
      standard deviation: 78.389 (0.307408)
      kurtosis: -1.21332
      skewness: -0.528275
      entropy: 0.964203
    Blue:
      min: 0 (0)
      max: 255 (1)
      mean: 157.743 (0.618599)
      standard deviation: 80.1038 (0.314133)
      kurtosis: -1.16231
      skewness: -0.640165
      entropy: 0.944264
  Image statistics:
    Overall:
      min: 0 (0)
      max: 255 (1)
      mean: 154.523 (0.605973)
      standard deviation: 78.4271 (0.307557)
      kurtosis: -1.27912
      skewness: -0.498417
      entropy: 0.9545
  Rendering intent: Perceptual
  Gamma: 0.454545
  Chromaticity:
    red primary: (0.64,0.33)
    green primary: (0.3,0.6)
    blue primary: (0.15,0.06)
    white point: (0.3127,0.329)
  Background color: white
  Border color: srgb(223,223,223)
  Matte color: grey74
  Transparent color: black
  Interlace: None
  Intensity: Undefined
  Compose: Over
  Page geometry: 1594x1200+0+0
  Dispose: Undefined
  Iterations: 0
  Compression: JPEG
  Quality: 80
  Orientation: Undefined
  Properties:
    comment: File source: https://commons.wikimedia.org/wiki/File:Salineras_de_Maras,_Maras,_Per%C3%BA,_2015-07-30,_DD_12.JPG
    date:create: 2016-05-11T10:27:35-07:00
    date:modify: 2016-05-11T10:27:34-07:00
    jpeg:colorspace: 2
    jpeg:sampling-factor: 2x2,1x1,1x1
    signature: 4c297af422b2e070f8d8ce17f7932e133afd03be2bf0eb133ee4d73485180bf1
  Profiles:
    Profile-icc: 524 bytes
  Artifacts:
    filename: 1594px-Salineras_de_Maras,_Maras,_Perú,_2015-07-30,_DD_12.JPG
    verbose: true
  Tainted: False
  Filesize: 576KB
  Number pixels: 1.913M
  Pixels per second: 47.82MB
  User time: 0.030u
  Elapsed time: 0:01.040
  Version: ImageMagick 6.9.3-7 Q16 x86_64 2016-03-27 http://www.imagemagick.org

Argh, that last line seems to be ImageMagick's identify command identifying itself? No idea what's generating the images then...

...but looking at CommonSettings.php we don't seem to have VIPS enabled for JPEGs in production:

	$wgVipsOptions = [
		[
			'conditions' => [
				'mimeType' => 'image/png',
				'minArea' => 2e7,
			],
		],
		[
			'conditions' => [
				'mimeType' => 'image/tiff',
				'minShrinkFactor' => 1.2,
				'minArea' => 5e7,
			],
			'sharpen' => [ 'sigma' => 0.8 ],
		],
	];

http://www.vips.ecs.soton.ac.uk/supported/7.42/doc/html/libvips/VipsForeignSave.html

vips_jpegsave ()

[...] no -subsample: disable chroma subsampling

We don't use that option, which means it does the default. Question is, what is VIPS' default behavior? I think we need to look at VIPS' code to be sure. TIFFs come in a very wide variety, no matter what sample set we use, it will never be exhaustive in terms of features.

OK, so "no_subsample" actually sets it to 4x4x4 https://github.com/jcupitt/libvips/blob/10fcbb6129804acc435603b4fd829085c3f0ff82/libvips/foreign/vips2jpeg.c#L1123-L1124

What it does in the default case is hard to tell. It looks like it's letting libjpeg do whatever its default is? Gotta look at that now I guess...

Found a comment from the maintainer of libjpeg-turbo that states that its default is 4:2:0. And in debian vips set its dependency on turbo and not plain libjpeg: https://packages.debian.org/fr/jessie/libvips-tools Meaning we should be all good.

@Jdforrester-WMF where did you see 4:2:2?