• This repository has been archived on 24/Oct/2019
  • Stars
    star
    103
  • Rank 333,046 (Top 7 %)
  • Language
    C++
  • Created over 13 years ago
  • Updated over 13 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Fork of the AdvanceCOMP re-compression utilities

AdvanceCOMP

The AdvanceCOMP recompression utilities is a suit of commands for optimizing the compression ratio for a number of zlib based file formats, such as .png, .mng, and .gz.

This is a fork of the AdvanceCOMP recompression utilities that has been modified by adding the advpngidat recompression tool that can recompress Apples iPhone optimized PNG proprietary format.

The files in the src/ directory are the unpacked contents of the advancecomp-1.15.tar.gz distribution.

See also:
    Xcode Build Setting Reference – COMPRESS_PNG_FILES (Compress .png files)
    Technical Q&A QA1681 – Viewing iPhone-Optimized PNGs
    CgBI file format

Usage

This fork of the AdvanceCOMP tools does not modify any of the original tools, but adds an additional tool– advpngidat.

The advpngidat tool has a couple of options, which you can view via --help, but there is really only one option that is used in practice: -z4. This specifies that the original .png file should be recompressed using the highest compression / maximum effort setting. For example:

shell% advpngidat -z4 FILE.png
      308008      283951  92% FILE.png

The original .png file is replaced with the recompressed version. The .png file is left unmodified if advpngidat was unable to make the .png smaller.

You can also wild-card batch process .png files too:

shell% advpngidat -z4 Images/*.png
         937         908  96% Images/[email protected]
      147935      136238  92% Images/Default.png
      523332      479938  91% Images/[email protected]
         127         127 100% Images/DottedLine.png (Bigger 133)
         148         148 100% Images/[email protected]

Helpful Hint: The AdvanceCOMP distribution also includes the advdef tool. This tool performs the same recompression optimization on .gz files, and it is used exactly the same way as advpngidat– advdef -z4 FILE.gz.

Design

The advpngidat tool was created by taking the repng.cc and copying it to repngidat.cc. The PNG optimization code from repng.cc was then completely removed, and code that only recompresses a PNG's IDAT chunk was added.

The advpngidat tool performs only a single type of optimization: recompression of the IDAT chunk in a .png file. The contents of the decompressed IDAT chunk are not examined nor modified in anyway, it is simply recompressed using the 7z RFC 1950 / zlib compression engine. The other PNG chunks in the .png file are passed through unmodified.

RFC 1950 / zlib Streams

RFC 1950 / zlib allows for two types of streams:

  • Normal. This stream type includes a header, trailer, and Adler-32 checksum of the data.
  • Raw. This stream type does not include a header, trailer, or a Adler-32 checksum.

The PNG specification mandates that the IDAT chunk be compressed using the normal, non-raw stream format.

The iPhone optimized PNG format requires the IDAT chunk to be compressed using the raw stream format.

Recompressing IDAT

The advpngidat tool works by recompressing the IDAT chunk using the 7z RFC 1950 / zlib compression engine, which can usually achieve an additional 3% to 7% additional compression relative to zlib / gzip -9 maximum compression setting (it's sort of like gzip that goes to gzip -11).

The iPhone optimized PNG format includes an additional, non-standard PNG chunk type: CgBI. The presence or absence of this chunk type is used to determine whether or not the IDAT chunk is a raw or normal RFC 1950 / zlib stream. The advpngidat tool works on either iPhone optimized .png files, or PNG standard conforming .png files. The presence or absence of a CgBI chunk is used to determine whether or not the IDAT chunk should be read and re-written as a raw or normal RFC 1950 / zlib stream.

Recompression Results

Some numbers (obtained with shell% wc Images/*.png | tail -1) based on the .png files in Resources/Images at the time of this writing:

Default Xcode pngcrush6554837 bytes (6.25MB)
After advpngidat6110164 bytes (5.82MB)

This represents a savings of 444673 bytes, or 434KB.

There is an additional option that you can use with pngcrush: -brute. This option tries a very large number of permutations of the various compression knobs, which means it can take a lot longer. Here's the results with -brute enabled:

Xcode pngcrush w/ -brute5626755 bytes (5.36MB)
After advpngidat5248702 bytes (5.00MB)

Using a combination of both -brute and advpngidat saves 1306135 bytes, or 1.24MB, relative to the default Xcode COMPRESS_PNG_FILES optimization.

Background / Theory

zlib is a LZ77 based compression scheme, and like all LZ77 based compressors, it uses a length, distance pair in the compressed byte stream that is used by the decompressed to copy length number of bytes from a position that is a distance number of bytes back from the bytes that have already been decompressed.

In practice, there are usually a number of possible matches for any given length, distance pair. Since the number of combinations raises very quickly, there is no practical way to find the combination that results in the smallest number of compressed bytes. A number of heuristics are used by LZ77 based compressors, and the compression ratio achieved by a particular implementation is highly dependent on the length, distance search algorithm used.

The AdvanceCOMP recompression tools use the search / match implementation from the 7-Zip / LZMA compression engine which has been specifically designed to maximize the compression ratio. The 7-Zip / LZMA matcher is typically able to get an additional 4% to 15% compression than zlib at its highest setting (i.e., gzip -9). Of course, it also takes a lot longer to perform the compression. Therefore it makes sense to spend the extra effort only when the files in question are of the "compress once, decompress many times" variety.

As a general rule, decompression speed of LZ77 based compressors is completely independent of the quality and implementation of the compressor. In fact, it usually takes less time to decompress a highly compressed LZ77 byte stream (i.e., AdvanceCOMP recompressed files) than it does to decompress a LZ77 byte stream that was created by a compressor that was optimized for compression speed (i.e., gzip -1). This is because a highly compressed LZ77 stream invariably contains less length, distance pairs that need to be processed, while the length, or the number of bytes copied, tends to be greater, and copying bytes is typically something that is highly optimized (i.e., memcpy).

More Repositories

1

Weaver

Dependency Injection framework for Swift (iOS/macOS/Linux)
Swift
735
star
2

LiveCollections

Automatically perform UITableView and UICollectionView animations between two sets of immutable data. It supports generic data types and is fully thread-safe.
Swift
340
star
3

robot-fruit-hunt

A fun little game that doubles as a JavaScript programming exercise.
JavaScript
142
star
4

SCPagingGridView

SCPagingGridView is a collection of iOS viewcontroller containers, views, & helpers.
Objective-C
122
star
5

objinsync

Continuously synchronize directories from remote object store to local filesystem
Go
93
star
6

Xcode-OptimizePNG

A modification for Xcodes 'Compress PNG Files' Build Setting
Shell
59
star
7

flash_heed

Fixes all Flash elements on a page so that they heed DOM stacking order.
JavaScript
45
star
8

terraform-aws-datadog

Terraform module for setting up AWS Datadog integration
HCL
38
star
9

rscribd

Ruby client library for the Scribd API
Ruby
32
star
10

FLBugKit

A simple library that allows users and testers to email bugs from within an iOS application
Objective-C
31
star
11

datadog_backup

Backup your Datadog account.
Ruby
30
star
12

hive-udaf-maxrow

A simple aggregate function (UDAF) for Hive -- like max() but it allows you to refer to additional columns in the maximal row.
Java
25
star
13

github-action-datadog-reporting

Ruby
22
star
14

scribd.github.io

The Scribd technology site, where we share the challenges in building the world's largest library
HTML
17
star
15

pr-preview-example

Pull Request Previews with Github Actions, AWS App Mesh, and ECS
HCL
15
star
16

keynote

keynote
Python
14
star
17

find-slack-user-action

GitHub Action that retrieves a Slack username for the author of the most recent commit (or provided email).
JavaScript
10
star
18

armadillo

A delightful audio player for Android.
Kotlin
10
star
19

Lucid

Lucid is a Swift library for building robust data layers for applications.
Swift
9
star
20

terraform-aws-recycle-eks

Terraform module for automatically recycling EKS worker nodes
Python
7
star
21

Meta

Generate beautiful code with plain code.
Swift
6
star
22

GAProxy

A wrapper for Google Analytics in Actionscript
ActionScript
6
star
23

go-sdk

Go SDK
Go
5
star
24

kafka-player

A simple scala app that plays messages from a file onto a Kafka topic.
Scala
5
star
25

vaulttest

Integration test Vault code locally!
Go
3
star
26

elasticache-slowlog-to-datadog

Use AWS Lambda to collect Elasticache Redis slowlog entries and submit to Datadog
Ruby
3
star
27

amazon-ecs-service-action

Amazon ECS Service Action for GitHub Actions
JavaScript
3
star
28

JSCRIBD

A Java library for interacting with the Scribd API.
Java
3
star
29

scribd-uploader-osx

A fully native Cocoa Macintosh uploader app for the Scribd.com website.
R
3
star
30

fastly-waf-ece

Event Correlation Engine for Fastly WAF Events ('event correlation engine' sounds a lot cooler than 'log smoosher')
Go
3
star
31

megaport-datadog

Publishing Megaport metrics to Datadog
Python
2
star
32

terraform-s3-rbac

Terraform module to allow users to easily create buckets in their own account and then give access to said buckets via AWS IAM principals
HCL
2
star
33

rails-git-scripts

A simple collection of useful scripts for Ruby on Rails developers who use Git
2
star
34

terraform-elasticache-slowlog-to-datadog

Deploy Elasticache Slowlog to Datadog lambda function to AWS account
HCL
2
star
35

terraform-aws-app-secrets

A Terraform module to create application secrets stored in AWS Secrets Manager.
HCL
1
star
36

amazon-appmesh-virtual-service-action

Amazon App Mesh Virtual Service Action for GitHub Actions
JavaScript
1
star
37

amazon-appmesh-route-action

Amazon App Mesh Route Action for GitHub Actions
JavaScript
1
star
38

tail-action

Github Action to retrieve the last n lines of a file or string.
1
star
39

.github

Default files for repositories across the organization
1
star
40

Coffee-Time-OSX

The Mac OS X front-end for Coffee Time.
Objective-C
1
star
41

job-notification

A GitHub Action for sending job notifications
1
star
42

amazon-appmesh-virtual-node-action

Amazon App Mesh Virtual Node Action for GitHub Actions
JavaScript
1
star
43

Coffee-Time-Backend

The Heroku back-end for Coffee Time.
Ruby
1
star
44

amazon-appmesh-virtual-gateway-route-action

Amazon App Mesh Virtual Gateway Route Action for GitHub Actions
JavaScript
1
star
45

amazon-appmesh-virtual-router-action

Amazon App Mesh Virtual Router Action for GitHub Actions
JavaScript
1
star
46

amazon-servicediscovery-service-action

Amazon ServiceDiscovery Service Action for GitHub Actionss
JavaScript
1
star
47

delta-lambdas

Collection of useful Lambda utilities for interacting with Delta Lake tables
Rust
1
star