Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Addition of variable JPEG2000 compression for different sizes #1

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Vary JPEG2000 compression levels by icon size for quality improvements
High JPEG2000 compression levels result in excellent results at large
image dimensions, but can cause very visible artefacting for smaller
icon dimensions.  This commit applies the specified compression level
for the large image sizes, applies less compression for 512*512 and
256*256 sizes, and disables compression for smaller sizes; this allows
JPEG2000 compression to be increased overall for much smaller file
sizes with no visible loss in quality, producing excellent output at
compression levels of 0.2-05 for most icons.

Also outputs the compression level being used for each size in the
output.
  • Loading branch information
rowanbeentje committed Dec 16, 2012
commit 8437b65c29f8ea2db40bcf1624ce95231fa310c8
38 changes: 33 additions & 5 deletions oldiconutil/main.m
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ int main(int argc, const char * argv[])
BOOL convertInPlace = NO;
BOOL listOnly = NO;
int nameArgumentPosition = 1;
NSNumber* jpegCompressionObj = [NSNumber numberWithFloat: 1.0];
float jpegCompressionLevel = 1.f;
NSNumber* jpegCompressionObj = [NSNumber numberWithFloat: jpegCompressionLevel];
NSBitmapImageFileType compressionType = NSJPEG2000FileType;
NSString* destCompression = @"jp2";

Expand Down Expand Up @@ -94,11 +95,10 @@ int main(int argc, const char * argv[])
}
}

// If a compression level has been specified, parse it from the remaining string and use it:
// If a compression level has been specified, parse it from the remaining string:
if( compStr.length > 0 )
{
float theCompression = [compStr floatValue];
jpegCompressionObj = [NSNumber numberWithFloat: theCompression];
jpegCompressionLevel = [compStr floatValue];
}
}

Expand Down Expand Up @@ -173,9 +173,37 @@ int main(int argc, const char * argv[])

if( shouldConvert )
{

// For JPEG2000, high compression levels work very well for large sizes,
// but cause very visible artefacts at smaller sizes. So if using JPEG2000
// output format, don't apply compression for small sizes; use the specified
// compression for the largest 1024*1024 (ic10) size, and use less compression
// for medium sizes.
float jpegCompressionForSize = jpegCompressionLevel;
if ( [destCompression isEqualToString:@"jp2"] ) {

// Use no compression for the smallest sizes (ic11: 16*16@2x; ic12: 32*32@2x, ic07: 128*128)
if ( strcmp(blockType, "ic11") == 0 || strcmp(blockType, "ic12") == 0 || strcmp(blockType, "ic07") == 0 ) {
jpegCompressionForSize = 1.f;

// For the 256*256 sizes, halve the compression level (ic08: 256*256; ic13: 128*128@2x)
} else if ( strcmp(blockType, "ic08") == 0 || strcmp(blockType, "ic13") == 0 ) {
jpegCompressionForSize = (jpegCompressionForSize + 1.f) / 2.f;

// For the 512*512 sizes, use three-quarter compression (ic09: 512*512, ic14: 256*256@2x)
} else if ( strcmp(blockType, "ic09") == 0 || strcmp(blockType, "ic14") == 0 ) {
jpegCompressionForSize = ((jpegCompressionForSize * 3) + 1.f) / 4.f;
}
}
jpegCompressionObj = [NSNumber numberWithFloat: jpegCompressionForSize];

if( !listOnly )
{
printf( "\tConverting PNG to %s\n", [destCompression UTF8String] );
if ( [destCompression isEqualToString:@"jp2"] || [destCompression isEqualToString:@"jpg"] ) {
printf( "\tConverting PNG to %s (JPEG compression %f)\n", [destCompression UTF8String], jpegCompressionForSize );
} else {
printf( "\tConverting PNG to %s\n", [destCompression UTF8String] );
}

NSBitmapImageRep * theImage = [[NSBitmapImageRep alloc] initWithData: currBlockData];
NSData * jp2Data = [theImage representationUsingType: NSJPEG2000FileType properties:
Expand Down