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

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

Issue 2245453002: Fix WIC encoder to support kJPEG_Type (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 4 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
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
3 * 3 *
4 * 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
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkTypes.h" 8 #include "SkTypes.h"
9 9
10 #if defined(SK_BUILD_FOR_WIN32) 10 #if defined(SK_BUILD_FOR_WIN32)
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 case kJPEG_Type: 76 case kJPEG_Type:
77 type = GUID_ContainerFormatJpeg; 77 type = GUID_ContainerFormatJpeg;
78 break; 78 break;
79 case kPNG_Type: 79 case kPNG_Type:
80 type = GUID_ContainerFormatPng; 80 type = GUID_ContainerFormatPng;
81 break; 81 break;
82 default: 82 default:
83 return false; 83 return false;
84 } 84 }
85 85
86 //Convert to 8888 if needed. 86 // First convert to BGRA if necessary.
87 const SkBitmap* bitmap; 87 const SkBitmap* bitmap;
88 SkBitmap bitmapCopy; 88 SkBitmap bitmapCopy;
89 if (kN32_SkColorType == bitmapOrig.colorType() && bitmapOrig.isOpaque()) { 89 if (kBGRA_8888_SkColorType == bitmapOrig.colorType()) {
90 bitmap = &bitmapOrig; 90 bitmap = &bitmapOrig;
91 } else { 91 } else {
92 if (!bitmapOrig.copyTo(&bitmapCopy, kN32_SkColorType)) { 92 if (!bitmapOrig.copyTo(&bitmapCopy, kBGRA_8888_SkColorType)) {
93 return false; 93 return false;
94 } 94 }
95 bitmap = &bitmapCopy; 95 bitmap = &bitmapCopy;
96 } 96 }
97 97
98 // We cannot use PBGRA so we need to unpremultiply ourselves 98 // WIC expects unpremultiplied pixels. Unpremultiply if necessary.
99 if (!bitmap->isOpaque()) { 99 if (kPremul_SkAlphaType == bitmap->alphaType()) {
100 SkAutoLockPixels alp(*bitmap); 100 SkAutoLockPixels alp(*bitmap);
101
102 uint8_t* pixels = reinterpret_cast<uint8_t*>(bitmap->getPixels()); 101 uint8_t* pixels = reinterpret_cast<uint8_t*>(bitmap->getPixels());
103 for (int y = 0; y < bitmap->height(); ++y) { 102 for (int y = 0; y < bitmap->height(); ++y) {
104 for (int x = 0; x < bitmap->width(); ++x) { 103 for (int x = 0; x < bitmap->width(); ++x) {
105 uint8_t* bytes = pixels + y * bitmap->rowBytes() + x * bitmap->b ytesPerPixel(); 104 uint8_t* bytes = pixels + y * bitmap->rowBytes() + x * bitmap->b ytesPerPixel();
106
107 SkPMColor* src = reinterpret_cast<SkPMColor*>(bytes); 105 SkPMColor* src = reinterpret_cast<SkPMColor*>(bytes);
108 SkColor* dst = reinterpret_cast<SkColor*>(bytes); 106 SkColor* dst = reinterpret_cast<SkColor*>(bytes);
109
110 *dst = SkUnPreMultiply::PMColorToColor(*src); 107 *dst = SkUnPreMultiply::PMColorToColor(*src);
111 } 108 }
112 } 109 }
113 } 110 }
114 111
112 // Finally, if we are performing a jpeg encode, we must convert to BGR.
113 void* pixels = bitmap->getPixels();
114 size_t rowBytes = bitmap->rowBytes();
115 SkAutoMalloc pixelStorage;
116 WICPixelFormatGUID formatDesired = GUID_WICPixelFormat32bppBGRA;
117 if (kJPEG_Type == fType) {
118 formatDesired = GUID_WICPixelFormat24bppBGR;
119 rowBytes = SkAlign4(bitmap->width() * 3);
120 pixelStorage.reset(rowBytes * bitmap->height());
121 for (int y = 0; y < bitmap->height(); y++) {
122 uint8_t* dstRow = SkTAddOffset<uint8_t>(pixelStorage.get(), y * rowB ytes);
123 for (int x = 0; x < bitmap->width(); x++) {
124 uint32_t bgra = *bitmap->getAddr32(x, y);
125 dstRow[0] = (uint8_t) (bgra >> 0);
126 dstRow[1] = (uint8_t) (bgra >> 8);
127 dstRow[2] = (uint8_t) (bgra >> 16);
128 dstRow += 3;
129 }
130 }
131
132 pixels = pixelStorage.get();
133 }
134
135
115 //Initialize COM. 136 //Initialize COM.
116 SkAutoCoInitialize scopedCo; 137 SkAutoCoInitialize scopedCo;
117 if (!scopedCo.succeeded()) { 138 if (!scopedCo.succeeded()) {
118 return false; 139 return false;
119 } 140 }
120 141
121 HRESULT hr = S_OK; 142 HRESULT hr = S_OK;
122 143
123 //Create Windows Imaging Component ImagingFactory. 144 //Create Windows Imaging Component ImagingFactory.
124 SkTScopedComPtr<IWICImagingFactory> piImagingFactory; 145 SkTScopedComPtr<IWICImagingFactory> piImagingFactory;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 198
178 //Set the size of the frame. 199 //Set the size of the frame.
179 const UINT width = bitmap->width(); 200 const UINT width = bitmap->width();
180 const UINT height = bitmap->height(); 201 const UINT height = bitmap->height();
181 if (SUCCEEDED(hr)) { 202 if (SUCCEEDED(hr)) {
182 hr = piBitmapFrameEncode->SetSize(width, height); 203 hr = piBitmapFrameEncode->SetSize(width, height);
183 } 204 }
184 205
185 //Set the pixel format of the frame. If native encoded format cannot match BGRA, 206 //Set the pixel format of the frame. If native encoded format cannot match BGRA,
186 //it will choose the closest pixel format that it supports. 207 //it will choose the closest pixel format that it supports.
187 const WICPixelFormatGUID formatDesired = GUID_WICPixelFormat32bppBGRA;
188 WICPixelFormatGUID formatGUID = formatDesired; 208 WICPixelFormatGUID formatGUID = formatDesired;
189 if (SUCCEEDED(hr)) { 209 if (SUCCEEDED(hr)) {
190 hr = piBitmapFrameEncode->SetPixelFormat(&formatGUID); 210 hr = piBitmapFrameEncode->SetPixelFormat(&formatGUID);
191 } 211 }
192 if (SUCCEEDED(hr)) { 212 if (SUCCEEDED(hr)) {
193 //Be sure the image format is the one requested. 213 //Be sure the image format is the one requested.
194 hr = IsEqualGUID(formatGUID, formatDesired) ? S_OK : E_FAIL; 214 hr = IsEqualGUID(formatGUID, formatDesired) ? S_OK : E_FAIL;
195 } 215 }
196 216
197 //Write the pixels into the frame. 217 //Write the pixels into the frame.
198 if (SUCCEEDED(hr)) { 218 if (SUCCEEDED(hr)) {
199 SkAutoLockPixels alp(*bitmap); 219 SkAutoLockPixels alp(*bitmap);
200 const UINT stride = (UINT) bitmap->rowBytes(); 220 hr = piBitmapFrameEncode->WritePixels(height,
201 hr = piBitmapFrameEncode->WritePixels( 221 (UINT) rowBytes,
202 height 222 (UINT) rowBytes * height,
203 , stride 223 reinterpret_cast<BYTE*>(pixels));
204 , stride * height
205 , reinterpret_cast<BYTE*>(bitmap->getPixels()));
206 } 224 }
207 225
208 if (SUCCEEDED(hr)) { 226 if (SUCCEEDED(hr)) {
209 hr = piBitmapFrameEncode->Commit(); 227 hr = piBitmapFrameEncode->Commit();
210 } 228 }
211 229
212 if (SUCCEEDED(hr)) { 230 if (SUCCEEDED(hr)) {
213 hr = piEncoder->Commit(); 231 hr = piEncoder->Commit();
214 } 232 }
215 233
216 return SUCCEEDED(hr); 234 return SUCCEEDED(hr);
217 } 235 }
218 236
219 /////////////////////////////////////////////////////////////////////////////// 237 ///////////////////////////////////////////////////////////////////////////////
220 238
221 static SkImageEncoder* sk_imageencoder_wic_factory(SkImageEncoder::Type t) { 239 static SkImageEncoder* sk_imageencoder_wic_factory(SkImageEncoder::Type t) {
222 switch (t) { 240 switch (t) {
223 case SkImageEncoder::kBMP_Type: 241 case SkImageEncoder::kBMP_Type:
224 case SkImageEncoder::kICO_Type: 242 case SkImageEncoder::kICO_Type:
225 case SkImageEncoder::kPNG_Type: 243 case SkImageEncoder::kPNG_Type:
244 case SkImageEncoder::kJPEG_Type:
226 break; 245 break;
227 default: 246 default:
228 return nullptr; 247 return nullptr;
229 } 248 }
230 return new SkImageEncoder_WIC(t); 249 return new SkImageEncoder_WIC(t);
231 } 250 }
232 251
233 static SkImageEncoder_EncodeReg gEReg(sk_imageencoder_wic_factory); 252 static SkImageEncoder_EncodeReg gEReg(sk_imageencoder_wic_factory);
234 253
235 DEFINE_ENCODER_CREATOR(ImageEncoder_WIC); 254 DEFINE_ENCODER_CREATOR(ImageEncoder_WIC);
236 255
237 #endif // defined(SK_BUILD_FOR_WIN32) 256 #endif // defined(SK_BUILD_FOR_WIN32)
OLDNEW
« no previous file with comments | « src/images/SkForceLinking.cpp ('k') | tests/EncodeTest.cpp » ('j') | tests/EncodeTest.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698