Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(46)

Side by Side Diff: Source/platform/image-encoders/skia/PNGImageEncoder.cpp

Issue 290893002: [wip] Add canvas.toDataURL("image/png") compression control Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Update after https://src.chromium.org/viewvc/blink?view=rev&revision=175387 Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/platform/image-encoders/skia/PNGImageEncoder.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2010, Google Inc. All rights reserved. 2 * Copyright (c) 2010, Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 *output++ = alpha; 61 *output++ = alpha;
62 } else { 62 } else {
63 *output++ = SkGetPackedR32(*input); 63 *output++ = SkGetPackedR32(*input);
64 *output++ = SkGetPackedG32(*input); 64 *output++ = SkGetPackedG32(*input);
65 *output++ = SkGetPackedB32(*input); 65 *output++ = SkGetPackedB32(*input);
66 *output++ = alpha; 66 *output++ = alpha;
67 } 67 }
68 } 68 }
69 } 69 }
70 70
71 static bool encodePixels(IntSize imageSize, unsigned char* inputPixels, bool pre multiplied, Vector<unsigned char>* output) 71 static bool encodePixels(IntSize imageSize, unsigned char* inputPixels, bool pre multiplied, int quality, Vector<unsigned char>* output)
72 { 72 {
73 imageSize.clampNegativeToZero(); 73 imageSize.clampNegativeToZero();
74 Vector<unsigned char> row; 74 Vector<unsigned char> row;
75 75
76 png_struct* png = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); 76 png_struct* png = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
77 png_info* info = png_create_info_struct(png); 77 png_info* info = png_create_info_struct(png);
78 if (!png || !info || setjmp(png_jmpbuf(png))) { 78 if (!png || !info || setjmp(png_jmpbuf(png))) {
79 png_destroy_write_struct(png ? &png : 0, info ? &info : 0); 79 png_destroy_write_struct(png ? &png : 0, info ? &info : 0);
80 return false; 80 return false;
81 } 81 }
82 82
83 // Optimize compression for speed. 83 int compression = static_cast<int>(quality / 10.0 + 0.5);
84 // The parameters are the same as what libpng uses by default for RGB and RG BA images, except: 84 if (compression > Z_BEST_COMPRESSION)
85 // - the zlib compression level is 3 instead of 6, to avoid the lazy Ziv-Lem pel match searching; 85 compression = Z_BEST_COMPRESSION;
86 // - the delta filter is 1 ("sub") instead of 5 ("all"), to reduce the filte r computations. 86 else if (compression < Z_BEST_SPEED)
87 // The zlib memory level (8) and strategy (Z_FILTERED) will be set inside li bpng. 87 compression = Z_BEST_SPEED;
88 // 88
89 // Avoid the zlib strategies Z_HUFFMAN_ONLY or Z_RLE. 89 if (quality <= 0) {
90 // Although they are the fastest for poorly-compressible images (e.g. photog raphs), 90 png_set_compression_level(png, Z_BEST_SPEED);
91 // they are very slow for highly-compressible images (e.g. text, drawings or business graphics). 91 png_set_filter(png, PNG_FILTER_TYPE_BASE, PNG_FILTER_NONE);
92 png_set_compression_level(png, 3); 92 } else if (compression <= 3) {
93 png_set_filter(png, PNG_FILTER_TYPE_BASE, PNG_FILTER_SUB); 93 // Optimize compression for speed.
94 // The parameters are the libpng defaults for RGB and RGBA images, excep t that:
95 // - the zlib compression level is lower than the libpng default 6,
96 // to avoid the lazy Ziv-Lempel match searching.
97 // - the delta filter is 1 ("sub"), instead of 5 ("all"), to reduce
98 // filter computations.
99 // Note: the zlib memory level (8) and strategy (Z_FILTERED) will be set inside
100 // libpng.
101 // Note: avoid the zlib strategies Z_HUFFMAN_ONLY or Z_RLE. Although the y are the
102 // fastest for poorly-compressible images (e.g. photographs) they are ve ry slow
103 // for highly-compressible images (e.g. text, drawings, and business gra phics).
104 png_set_compression_level(png, compression);
105 png_set_filter(png, PNG_FILTER_TYPE_BASE, PNG_FILTER_SUB);
106 } else if (compression <= 7) {
107 png_set_compression_level(png, compression);
108 png_set_filter(png, PNG_FILTER_TYPE_BASE, PNG_FILTER_PAETH);
109 } else {
110 png_set_compression_level(png, compression);
111 }
94 112
95 png_set_write_fn(png, output, writeOutput, 0); 113 png_set_write_fn(png, output, writeOutput, 0);
96 png_set_IHDR(png, info, imageSize.width(), imageSize.height(), 114 png_set_IHDR(png, info, imageSize.width(), imageSize.height(),
97 8, PNG_COLOR_TYPE_RGB_ALPHA, 0, 0, 0); 115 8, PNG_COLOR_TYPE_RGB_ALPHA, 0, 0, 0);
98 png_write_info(png, info); 116 png_write_info(png, info);
99 117
100 unsigned char* pixels = inputPixels; 118 unsigned char* pixels = inputPixels;
101 row.resize(imageSize.width() * sizeof(SkPMColor)); 119 row.resize(imageSize.width() * sizeof(SkPMColor));
102 const size_t pixelRowStride = imageSize.width() * 4; 120 const size_t pixelRowStride = imageSize.width() * 4;
103 for (int y = 0; y < imageSize.height(); ++y) { 121 for (int y = 0; y < imageSize.height(); ++y) {
104 if (premultiplied) { 122 if (premultiplied) {
105 preMultipliedBGRAtoRGBA(pixels, imageSize.width(), row.data()); 123 preMultipliedBGRAtoRGBA(pixels, imageSize.width(), row.data());
106 png_write_row(png, row.data()); 124 png_write_row(png, row.data());
107 } else 125 } else
108 png_write_row(png, pixels); 126 png_write_row(png, pixels);
109 pixels += pixelRowStride; 127 pixels += pixelRowStride;
110 } 128 }
111 129
112 png_write_end(png, info); 130 png_write_end(png, info);
113 png_destroy_write_struct(&png, &info); 131 png_destroy_write_struct(&png, &info);
114 return true; 132 return true;
115 } 133 }
116 134
117 bool PNGImageEncoder::encode(const SkBitmap& bitmap, Vector<unsigned char>* outp ut) 135 bool PNGImageEncoder::encode(const SkBitmap& bitmap, int quality, Vector<unsigne d char>* output)
118 { 136 {
119 SkAutoLockPixels bitmapLock(bitmap); 137 SkAutoLockPixels bitmapLock(bitmap);
120 138
121 if (bitmap.colorType() != kPMColor_SkColorType || !bitmap.getPixels()) 139 if (bitmap.colorType() != kPMColor_SkColorType || !bitmap.getPixels())
122 return false; // Only support 32 bit/pixel skia bitmaps. 140 return false; // Only support 32 bit/pixel skia bitmaps.
123 141
124 return encodePixels(IntSize(bitmap.width(), bitmap.height()), static_cast<un signed char*>(bitmap.getPixels()), true, output); 142 return encodePixels(IntSize(bitmap.width(), bitmap.height()), static_cast<un signed char*>(bitmap.getPixels()), true, quality, output);
125 } 143 }
126 144
127 bool PNGImageEncoder::encode(const ImageDataBuffer& imageData, Vector<unsigned c har>* output) 145 bool PNGImageEncoder::encode(const ImageDataBuffer& imageData, int quality, Vect or<unsigned char>* output)
128 { 146 {
129 return encodePixels(imageData.size(), imageData.data(), false, output); 147 return encodePixels(imageData.size(), imageData.data(), false, quality, outp ut);
130 } 148 }
131 149
132 } // namespace WebCore 150 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/platform/image-encoders/skia/PNGImageEncoder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698