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

Side by Side Diff: src/ports/SkImageDecoder_CG.cpp

Issue 17084012: Fixes for unpremul decode. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 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 | « no previous file | tests/ImageDecodingTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1
2 /* 1 /*
3 * Copyright 2008 The Android Open Source Project 2 * Copyright 2008 The Android Open Source Project
4 * 3 *
5 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 5 * found in the LICENSE file.
7 */ 6 */
8 7
8 #include "SkCGUtils.h"
9 #include "SkColorPriv.h" 9 #include "SkColorPriv.h"
10
11 #include "SkImageDecoder.h" 10 #include "SkImageDecoder.h"
12 #include "SkImageEncoder.h" 11 #include "SkImageEncoder.h"
13 #include "SkMovie.h" 12 #include "SkMovie.h"
14 #include "SkStream.h" 13 #include "SkStream.h"
15 #include "SkTemplates.h" 14 #include "SkTemplates.h"
16 #include "SkCGUtils.h" 15 #include "SkUnPreMultiply.h"
17 16
18 #ifdef SK_BUILD_FOR_MAC 17 #ifdef SK_BUILD_FOR_MAC
19 #include <ApplicationServices/ApplicationServices.h> 18 #include <ApplicationServices/ApplicationServices.h>
20 #endif 19 #endif
21 20
22 #ifdef SK_BUILD_FOR_IOS 21 #ifdef SK_BUILD_FOR_IOS
23 #include <CoreGraphics/CoreGraphics.h> 22 #include <CoreGraphics/CoreGraphics.h>
24 #include <ImageIO/ImageIO.h> 23 #include <ImageIO/ImageIO.h>
25 #include <MobileCoreServices/MobileCoreServices.h> 24 #include <MobileCoreServices/MobileCoreServices.h>
26 #endif 25 #endif
(...skipping 16 matching lines...) Expand all
43 CGImageSourceRef imageSrc = CGImageSourceCreateWithDataProvider(data, 0); 42 CGImageSourceRef imageSrc = CGImageSourceCreateWithDataProvider(data, 0);
44 CGDataProviderRelease(data); 43 CGDataProviderRelease(data);
45 return imageSrc; 44 return imageSrc;
46 } 45 }
47 46
48 class SkImageDecoder_CG : public SkImageDecoder { 47 class SkImageDecoder_CG : public SkImageDecoder {
49 protected: 48 protected:
50 virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode); 49 virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode);
51 }; 50 };
52 51
52 // Returns an unpremultiplied version of color. It will have the same ordering a nd size as an
53 // SkPMColor, but the alpha will not be premultiplied.
54 static SkPMColor unpremultiply_pmcolor(SkPMColor color) {
55 U8CPU a = SkGetPackedA32(color);
reed1 2013/06/14 19:38:20 possibly only do this if a is != 0xFF and a != 0 ?
56 const SkUnPreMultiply::Scale scale = SkUnPreMultiply::GetScale(a);
57 return SkPackARGB32NoCheck(a,
58 SkUnPreMultiply::ApplyScale(scale, SkGetPackedR32 (color)),
59 SkUnPreMultiply::ApplyScale(scale, SkGetPackedG32 (color)),
60 SkUnPreMultiply::ApplyScale(scale, SkGetPackedB32 (color)));
61 }
62
53 #define BITMAP_INFO (kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast) 63 #define BITMAP_INFO (kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast)
54 64
55 bool SkImageDecoder_CG::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { 65 bool SkImageDecoder_CG::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
56 CGImageSourceRef imageSrc = SkStreamToCGImageSource(stream); 66 CGImageSourceRef imageSrc = SkStreamToCGImageSource(stream);
57 67
58 if (NULL == imageSrc) { 68 if (NULL == imageSrc) {
59 return false; 69 return false;
60 } 70 }
61 SkAutoTCallVProc<const void, CFRelease> arsrc(imageSrc); 71 SkAutoTCallVProc<const void, CFRelease> arsrc(imageSrc);
62 72
(...skipping 10 matching lines...) Expand all
73 return true; 83 return true;
74 } 84 }
75 85
76 if (!this->allocPixelRef(bm, NULL)) { 86 if (!this->allocPixelRef(bm, NULL)) {
77 return false; 87 return false;
78 } 88 }
79 89
80 bm->lockPixels(); 90 bm->lockPixels();
81 bm->eraseColor(SK_ColorTRANSPARENT); 91 bm->eraseColor(SK_ColorTRANSPARENT);
82 92
83 // use the same colorspace, so we don't change the pixels at all 93 CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
84 CGColorSpaceRef cs = CGImageGetColorSpace(image);
85 CGContextRef cg = CGBitmapContextCreate(bm->getPixels(), width, height, 8, b m->rowBytes(), cs, BITMAP_INFO); 94 CGContextRef cg = CGBitmapContextCreate(bm->getPixels(), width, height, 8, b m->rowBytes(), cs, BITMAP_INFO);
86 if (NULL == cg) { 95 CFRelease(cs);
87 // perhaps the image's colorspace does not work for a context, so try ju st rgb 96
88 cs = CGColorSpaceCreateDeviceRGB();
89 cg = CGBitmapContextCreate(bm->getPixels(), width, height, 8, bm->rowByt es(), cs, BITMAP_INFO);
90 CFRelease(cs);
91 }
92 CGContextDrawImage(cg, CGRectMake(0, 0, width, height), image); 97 CGContextDrawImage(cg, CGRectMake(0, 0, width, height), image);
93 CGContextRelease(cg); 98 CGContextRelease(cg);
94 99
95 CGImageAlphaInfo info = CGImageGetAlphaInfo(image); 100 CGImageAlphaInfo info = CGImageGetAlphaInfo(image);
96 switch (info) { 101 switch (info) {
97 case kCGImageAlphaNone: 102 case kCGImageAlphaNone:
98 case kCGImageAlphaNoneSkipLast: 103 case kCGImageAlphaNoneSkipLast:
99 case kCGImageAlphaNoneSkipFirst: 104 case kCGImageAlphaNoneSkipFirst:
100 SkASSERT(SkBitmap::ComputeIsOpaque(*bm)); 105 SkASSERT(SkBitmap::ComputeIsOpaque(*bm));
101 bm->setIsOpaque(true); 106 bm->setIsOpaque(true);
102 break; 107 break;
103 default: 108 default:
104 // we don't know if we're opaque or not, so compute it. 109 // we don't know if we're opaque or not, so compute it.
105 bm->computeAndSetOpaquePredicate(); 110 bm->computeAndSetOpaquePredicate();
106 } 111 }
112 if (!bm->isOpaque() && this->getRequireUnpremultipliedColors()) {
113 // CGBitmapContext does not support unpremultiplied, so the image has be en premultiplied.
114 // Convert to unpremultiplied.
115 for (int i = 0; i < width; ++i) {
116 for (int j = 0; j < height; ++j) {
117 uint32_t* addr = bm->getAddr32(i, j);
118 *addr = unpremultiply_pmcolor(*addr);
119 }
120 }
121 }
107 bm->unlockPixels(); 122 bm->unlockPixels();
108 return true; 123 return true;
109 } 124 }
110 125
111 /////////////////////////////////////////////////////////////////////////////// 126 ///////////////////////////////////////////////////////////////////////////////
112 127
113 extern SkImageDecoder* image_decoder_from_stream(SkStream*); 128 extern SkImageDecoder* image_decoder_from_stream(SkStream*);
114 129
115 SkImageDecoder* SkImageDecoder::Factory(SkStream* stream) { 130 SkImageDecoder* SkImageDecoder::Factory(SkStream* stream) {
116 SkImageDecoder* decoder = image_decoder_from_stream(stream); 131 SkImageDecoder* decoder = image_decoder_from_stream(stream);
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 295
281 SkAutoTCallVProc<const void, CFRelease> arsrc(imageSrc); 296 SkAutoTCallVProc<const void, CFRelease> arsrc(imageSrc);
282 const CFStringRef name = CGImageSourceGetType(imageSrc); 297 const CFStringRef name = CGImageSourceGetType(imageSrc);
283 if (NULL == name) { 298 if (NULL == name) {
284 return SkImageDecoder::kUnknown_Format; 299 return SkImageDecoder::kUnknown_Format;
285 } 300 }
286 return UTType_to_Format(name); 301 return UTType_to_Format(name);
287 } 302 }
288 303
289 static SkTRegistry<SkImageDecoder::Format, SkStream*> gFormatReg(get_format_cg); 304 static SkTRegistry<SkImageDecoder::Format, SkStream*> gFormatReg(get_format_cg);
OLDNEW
« no previous file with comments | « no previous file | tests/ImageDecodingTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698