关于JPEG的那点事儿

将此文献给自己掉进兔子洞里消失的几小时光阴(笑)

今天有友人随便问了个问题:为什么Leanify这款软件能无损在已经压缩率很高的JPEG再压缩个5%-10%。当然直接的答案很简单:mozjpeg压缩算法。不过这并没有解决我们的疑问,具体的实现方式呢?尤其是无损优化是怎么做到的?

把Leanify的源代码拖下来看了下,首先一部分优化是来自于删掉metadata——大概能节省下去十几到几十KB而已。剩下的就是来自Mozjpeg的部分了。如果你有像我蛋疼地研究过jpeg的specification或者压缩原理(提示:Wikipedia就是个好去处,没必要去啃ISO的标准……),应该知道就和所有的压缩程序一样,虽然JPEG算法核心是有损压缩,但是为了最大化压缩效果,最后肯定会来一步熵编码(在JPEG语境下,又分霍夫曼和步进[progressive]编码)。所以我的猜想就是mozjpeg用了什么黑科技来优化熵编码。在浪费了1个小时调试Leanify的源代码后,我失望地发现mozjpeg的熵编码本身并无特殊之处——事实上,mozjpeg的核心代码来自libjpeg-turbo,而我拿libjpeg-turbo的原始文件替换相应的熵编码部分后(其实这部分本来就没被Mozilla修改),mozjpeg的再压缩能力丝毫没有受到影响:我用XnView编码出的已经开启霍夫曼和步进编码的jpeg依然可以有不小的(~5%)大小缩减。

柳暗花明,随便浏览之前打开的相关网页时看到了libjpeg-turbo作者对mozjpeg的回应——里面其实已经有了正确答案。引用作者原话:

mozjpeg relies on three technologies (progressive JPEG encoding, jpgcrush, and trellis quantization) to reduce the size of JPEG images.

mozjpeg其实用了三个技术来优化JPEG——强制开启前面提到过的步进编码(光这最基本的一步就能优化不少了,很多家用的图像软件却没这选项)、jpgcrush和trellis quantization(网格量化?)。jpgcrush是由x264主要开发者Loren Merritt闲着没事儿(大误)写的perl脚本源代码),被mozjpeg在首发版本中集成到libjpeg-turbo中。其工作原理其实也很简单——在步进编码模式下不断尝试,直至找到最好的配置。至于我为啥看代码没发现这块?呃这算法的实现好像混在一堆叫scan的逻辑判断和循环之中,我以为是无关的代码就略过了……当然主要原因是我的三脚猫功夫啦。在mozjpeg 2.0中引入的Trellis quantization则是一种“更智能的来决定应该丢掉哪些信息的算法”(是不是耳熟?想想音频压缩),是从人的感知出发来在DCT部分做手脚,所以这个其实并不是无损压缩的范畴了,而是提供一种更优良的兼容于JPEG框架内的编码算法,在我们的问题中(jpeg->jpeg无损[逐像素]转换)不涉及。顺便一提,trellis quantization的实现又是最早出现在视频编码中——再想想webp也是来自于Google在VP系列视频codec的研究成果,现在图像编码这方面的开发已经完全是视频带着图像走了。

在该文中,libjpeg-turbo的作者同时对mozjpeg的压缩效率以及必要性产生了一些质疑。用作者的话说,mozjpeg虽然可以增加少许压缩率不过速度比libjpeg-turbo慢了几十倍。作者同时抱怨了随着新功能的引入,mozjpeg也破坏了兼容性。作为被fork的本体,libjpeg-turbo不会跟进这些更新。不过作者同时也对其开发目的表示了理解(极限压缩),只是两者用途不同,外加自己本来就是义务开发又被众多开源计划使用(Mozilla家的Firefox都依然在继续用libjpeg-turbo),稳定性第一,实验功能可以再观察观察。虽然话不好听,相信两者之间应该还是比较愉快的,毕竟在mozjpeg 3.0的更新中就专门加强了ABI(应用二进制接口)上对libjpeg-turbo的兼容性。

有人可能忍不住了,libjpeg-turbo到底是什么鬼?这说来又话长了。JPEG是“联合图像专家小组”的意思,其实就是这种编码方法的创始者。不过,JPEG编码的具体实现,libjpeg,则是由一个独立的开发小组——(IJG,Independent JPEG Group)在1991年发布的,这甚至比JPEG的初版标准出炉还早1年。其领衔开发者是Tom Lane,这家伙也是开源界神人一枚,光在图像界就至少参与了JPEG、PNG和TIFF的开发。随着时间的发展,libjpeg逐渐成为了JPEG的标准实现,与此同时JPEG也慢慢成为使用最多的图像格式。不过libjpeg的开发在1998年引入了上面提过多次的步进编码之后就停滞在了ver. 6b上。在整整11年之后,更换了领导的IJG终于发布了ver. 7——其中一个修改是引入了算术编码的新熵编码方式,相比霍夫曼它可以再提升百分之几的无损压缩率。其实这不是什么新东西,JPEG最初的标准里就有,但是这玩意曾经有大批专利掌握在IBM手中,所以直到专利过期才敢加入进来。IJG的脚步并没有就此停止,在最近几年其接连发布了版本8、版本9,增加了一些诸如无损JPEG(同算术编码,无损JPEG也是最初JPEG标准里就有的东西,但是一直没有被实现)、动态“智能”调整DCT block大小(原先是固定8×8)之类的功能。然而,社群对这些新功能并不怎么感冒——因为他们和已经用了十几年的6.x并不兼容,而且性能非常值得怀疑。连IJG的创始人,前面提过的Lane,都出来发声反对。更糟糕的是,关于将动态DCT block等功能加入标准的提案也被管理JPEG的标准化组织之一ITU-T拒绝——这意味着,libjpeg已经在自创一种JPEG之上的新标准了(虽然这种生米煮成熟饭的事儿在IT界屡见不鲜):说得好听叫更先进,说的难听叫(无人支持的)自主标准。libjpeg的新领头人Guido Vollbeding也相当高调,经常在社群里和别人打嘴仗,甚至在维基百科的libjpeg条目中和别人打编辑战

就在IJG重启开发的同一时期,一个名叫libjpeg-turbo的新fork出现,其最初目的在提升libjpeg的性能。对于libjpeg新版本的争议,libjpeg-turbo的作者则决定依然基于6b开发,同时提供了一些对7/8的ABI/API模拟。作者也写了文章表明,libjpeg这些新功能性能提升很细微,尤其是无损JPEG无论是质量还是速度都劣于webp,甚至在大部分时候都不如PNG。很快,开源社区就全面转向了libjpeg-turbo。不过这里顺便提一句,虽然turbo已经支持了算术编码,但是绝大部分开源社区默认都不使用甚至移除相关代码,为了规避可能的专利风险。在libjpeg v9出来之后,turbo的作者更明确表达对libejpeg开发思路的不满,决定不再去模拟9版本,从此和libjpeg划清界限。

故事到这里也算告一段落了。libjpeg-turbo继续作为新的事实标准,使用在各大OS发行版以及其他重量级软件(如Chrome、Firefox)中;IJG也继续在开发他们的libjpeg的新版本,今年年初才公布了9b;mozjpeg在去年更新3.1之后则暂时消停了,不过这种东西本来也没有快速更新的必要。说到底,作为快三十岁的老格式,JPEG还能散发活力就已经很了不起了。

于是又几个小时的光阴没有了

Part2:关于JPEG的那点事儿 Part 2:JPEG原理

值得关注的小软件

个人备份用。记录一些现在偶尔在用、或是将来可能会有用的不错的小软件,主要是存档给自己看的。随时更新。更新的加在最前面。

[Apr 11 2016 更新]

Seer

国人开发的一个用途很……niche的一个小软件。其作用就是在资源管理器(或者桌面,任何能展示文件的地方)中选择一个文件然后按空格,会预览那个文件。支持各种格式,从txt到图片、到视频到压缩包无所不包。目前而言效果是不错,但是不知道用途有多广?毕竟大多数软件现在开启速度都很快了,很多时候预览不如直接打开。

dupeGuru

搜Duplicate finder的第一个结果。没有仔细用,感觉还有待提高,暂时放到这里下次需要时再详细试试。

[Apr 5 2016 更新]

WhatPulse

输入(键盘、鼠标点击)统计软件。可以统计热点地图,包含屏幕点击位置、键盘按键次数等等。对于游戏玩家可能会有用——至少很有趣。

[Feb 15 2016更新]

Default Programs Editor

修改文件关联、图标、默认程序等等相关的东西。说白了就是把之前只能在注册表里手动操作的东西可视化了。我一直在找这样的软件来着,今天恰好看到Reddit推荐。UI很直观好用,虽然操作稍嫌啰嗦。

Unchecky

自动在安装其他软件的过程中去掉可疑的捆绑软件的选项。对疯狂下一步的用户有奇效。

但是这货需要把自己当做一个后台一直运行,总感觉挺蛋疼的…

MysticThumbs

类似FastPictureViewer Codec Pack(收费软件)或者SageThumbs第三方资源管理器略缩图Codec包,由于我现在在用SageThumbs所以这个暂时不用。

KeyPosé & KeyCastOW

两个可以在屏幕上显示按下键盘的软件,便于录制教程等用。更推荐后者,选项更多,效果更好。

TreeSizeFree & WizTree & Free Disk Analyzer

我知道大家一般用SpaceSniffer比较多,但是很多时候我觉得树状列表会更方便一些。这三款是我从此文中挑出的UI比较舒服的,各有优缺,基本功能都差不多,就是按照查看磁盘空间占用最多的文件夹/文件。

Shotty

一款截图软件,最大也许是唯一的优点是,截图Windows窗口可以保存透明Aero特效,效果非常漂亮。

LICEcap

可能是这里用得最多的软件了,快速截图屏幕制作GIF的小软件,非常方便。

打开多个Excel实例来规避多文件修改历史(撤销、重做)混合在一起的问题

说实话我Excel用的不多,居然直到今天才发现有这个问题。

标题很难说清,其实就是,在Excel中,如果你打开了多个文件,那么所有文件的编辑历史——也就是你可以撤销的操作,是全部混在一起的。例如你打开了文件A和B,然后先在A中进行了一系列操作,又切换到B中进行了另一系列操作。这时你切换回文件A,按下ctrl+Z,你会发现你撤销的还是在B中的操作,而不是A的。这种奇怪的行为模式和几乎所有其他软件,包括Office中的其他软件如Word、PowerPoint,都不一样。微软这么做可能有他自己的考虑,比如交叉操作等等,但是事实是用户实在是很难适应这种别扭的方式。

微软暂时无意修改的前提下,倒是有workaround可以规避这一问题。方法就是打开多个Excel实例——然后在新的实例中手动打开想要的第二个文件(而不是直接双击文件)。

要打开新的实例,有两个方法(方法来自superuser这帖):

  1. 方法一:打开第一个实例之后,按住alt键,再次点击Excel图标(可以通过桌面、开始菜单、任务栏中键点击等方式)启动。注意,直至

    2016-01-15
    这一图像出现前,不要松开alt键。然后选择是即可。这样开出来的Excel就是新的实例。

  2. 方法二:在命令行(Win+R)直接运行excel /x 即可。

再见Yahoo

本文为纯抱怨贴,进入请谨慎。

绝大部分IT巨头的服务/产品都有一个共同点:缺乏客户服务,准确地说是人工客户服务。因此,也严重缺乏用户的反馈渠道。不信?尝试能不能在5分钟内找到Google的人工客服(提示:是存在的,by email)?

某种意义上可以理解,因为他们的用户实在是太多,而且产品线也极广,如果想做到像传统行业那样程度的“售后”,估计那么那几万员工天天也不用干别的了。对应的解决方案一般是庞大的知识库+用户交流论坛(社区类型,仅有少部分官方人员)。前者就不必说,后者这方面微软算做得比较好,至少微软的用户论坛人气一直都不错,而且真的能找到解决方案。

但是凡是问题牵扯到技术层面(换句话说,产品本身的BUG而非用户自己使用方法不对的情况下),很多时候你就会发现根本无门反映。比如Google maps有个很愚蠢的显示错误:在地球(Eearth)模式下,中文和日文界面(天知道别的语言是否也有同样问题)的“3D on”的开关标示是反的:

JapaneseEnglish ChineseTW

这种问题大概i18n团队几分钟就能解决,但是去哪告诉他们呢?我去Productforums发了一贴,也在Maps里发了几个feedback,目前没任何动静。

实话说,大部分用户,可能99%的用户都很蠢,他们会在自己使用方法不对的情况下就开始抱怨,缺乏基本的排错能力,更完全无法提出任何建设性的东西,这点我们无法否认。这也就是为什么Firefox的官方“客服”论坛是个灾难的缘故。但是对于Firefox(或者其他什么开源软件),我们另外还有Bugzilla——所有产品的Bug我们可以去那里汇报。然而对于大部分互联网服务,这样的技术性的反馈渠道是不存在的。而且很多时候你也很难分清所谓的Bug是不是有意为之。同样的问题其实现实中也存在:大家应该都有经历过给ISP打电话说网络不通、先让你重启路由器的事儿吧?

好了回到雅虎。雅虎在2013年关闭大陆服务之后,我一直以为我应该不会受到影响——因为我的yahoo ID申请的很早,而且是@yahoo.com的。事实上这个ID一会在yahoo主站(美国)确实可以登录,我还拿它绑定了Flickr等一些雅虎服务。结果前一段突发奇想想试下雅虎的邮箱,就发现完全登不进去。经过一番研究之后我确定我原来的邮箱服务还是基于大陆的,所以在关闭事件之后就没了。

OK,现在问题来了:我不需要那个邮箱上的任何东西,我只是想用雅虎的邮箱服务而已(事实上雅虎其他的服务我都可以无问题地使用),所以你让我开个新的总可以吧?然而似乎并没有这样的渠道可以这样做。在经历了第一段所述的,花了高达10分钟找“Contact us”按钮的过程后我发现雅虎似乎并没有真正意义上的人工客服…于是我转而去twitter给客服账号发了条PM。回复倒是蛮快的:“你的账号依然挂在中国那边,你去找yahoo TW的客服吧用这个地址。”姑且不论TW和CN根本不是一家,我们先试试。结果TW那边的回复是:“我们没法查看或者修改来自大陆的账号。如果你想用邮箱,可以建立个新号。”

本来对雅虎这账号还有点感情(虽然实话说,除了Flickr我基本没用过任何雅虎服务,纯粹是自己矫情啦),看到这句话直接恶心到了。于是速速去把flickr绑了个新雅虎账号,然后把老号删了。哦,顺便一提,要删掉你的雅虎账号,你需要手动输入一串链接。是的,并没有任何按钮或者选项你可以直接找到。

So why yahoo is still relevant again?

少年刑警

自从布卡删了不少漫画之后看漫画的频率越来越低,而且看多了现在想找到我喜欢的题材外加“有台版、卷数不超过20、最好完结”(个人癖好,不喜欢超长作品,不喜汉化组翻译)的作品还真是挺难的。

这部作品是在布卡评论里别人提到的。其实乍一眼和之前看的一部叫《PS -罗生门-》的警察青年漫画很像。和罗生门一样,本作也是讲菜鸡警官逐渐成长的故事。不同之处在于,所谓少年刑警——是一位外表看似小孩,智慧却过于常人——啊抱歉,拿错台词本了,是一位虽然是正牌警官,外貌却停留在国中生程度的热血新兵警察在少年科办案的故事。

这类以上班族而非学生为背景的青年漫画中(的一部分)有个特点,就是整体的风格都是偏向“鸡汤”、“圣母”类。说实话,可能不是很对这一代的胃口,尤其是考虑到现在的漫画都竭尽所能走负能量猎奇的噱头路线。但是考虑到其目标受众,也不难理解——谁愿意上了一天班还看负能量啊?

不过后来发现这部漫画虽然主题上和中心思想上和上面那部很接近,但他确实一部实打实的少年漫画。故事的虚幻和戏剧程度也因此高了很多,比如从题材上“少年科警察”就很讨巧地、虽然看似是讲社会人但是大部分时间都在和中学生打交道,又比如日本少年向作品中热衷的男主酷炫掉渣天的能力(在本作中是男主的剑道,已经达到了神鬼级的地步)。其中有些梗比如利用男主的身体条件(?)去打入中学内部卧底也是一而再再而三地用到吐。哦等等我是不是还忘了说男主还有能看出人快死了的超能力来着?

但是总体而言,本作的剧情还算中规中矩,格局小但是也没有大野心(这里废言几句,其实个人很喜欢日本的小格局作品,但是很多走正剧路线的轻小说、原创动画总是硬是去试图塑造超出能力范围的大格局作品,结果只会生出来让人看着发笑的一个个怪胎)。不过又有些反常的是,在几个后期案件的情节处理上作者选择了残酷路线,和这类作品一贯走温情、励志方向不太相符。恶意揣测一下,可能某种意义上是为了噱头?尤其是考虑到片中侧面提到强奸事件的次数之多,不能不让人浮想。当然了,故事的最后男主最后依然还是要灭掉不听话的,感化洗白其他的啦。

人物塑造方面基本是模板化了大部分配角突出了男主一个人,也不能算失败。但是有些时候为了推动剧情随意调整之前角色的行为方式,感觉还是略显都合(比如那个掉光牙的吸毒妹,一会正一会反,变脸比那啥还快)。

另外稍显遗憾地是,对于少年犯问题的深入讨论,显然不是本作力所能及的范畴。不过可喜的是,除了批判“少年法=少年犯保护法”这一无论是中国还是日本都是很讨喜的“主流”(注意引号,这里的主流是指在特定政治倾向的人群中主流)论调的观点之外,作者也从另一个立场大量着墨了少年犯努力试图重返社会的、成功的不成功的尝试。相比之下《17岁。》那种描写我觉得就稍显沉重而且缺乏讨论可能性的空间。

本漫画值得一提的是画风。作画者朝基まさし我没有听过,不过搜了下其前作《感应少年EIJI》的画风其实更接近甲斐谷忍…不过到了这作明显风格就圆润了许多,其笔下的女主人公也是相当地讨人喜欢。有人说像小畑健?

女神
总分7分吧,十几卷的容量而已,个人觉得即使看看女主卖萌也不算亏。哦好像本作还有改编成日剧来着,但是似乎评价很烂。