blob: 7af47a697ec6a21d4092b4a766fbbd030d976bde [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
reed@android.com8a1c16f2008-12-17 15:59:43 +00008#include "SampleCode.h"
9#include "SkView.h"
10#include "SkCanvas.h"
halcanary@google.com9acb8cd2014-01-10 14:53:49 +000011#include "SkData.h"
12#include "SkDecodingImageGenerator.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000013#include "SkGradientShader.h"
14#include "SkGraphics.h"
reed@android.com791f5a12009-03-16 13:53:11 +000015#include "SkImageDecoder.h"
reed@android.comb08eb2b2009-01-06 20:16:26 +000016#include "SkImageEncoder.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000017#include "SkPath.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000018#include "SkRegion.h"
19#include "SkShader.h"
20#include "SkUtils.h"
21#include "SkXfermode.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000022#include "SkColorPriv.h"
23#include "SkColorFilter.h"
24#include "SkTime.h"
25#include "SkTypeface.h"
26
reed@android.com8a1c16f2008-12-17 15:59:43 +000027#include "SkStream.h"
28
29static void make_image(SkBitmap* bm, SkBitmap::Config config, int configIndex) {
30 const int width = 98;
31 const int height = 100;
32 SkBitmap device;
rmistry@google.comae933ce2012-08-23 18:19:56 +000033
reed@android.com8a1c16f2008-12-17 15:59:43 +000034 device.setConfig(SkBitmap::kARGB_8888_Config, width, height);
35 device.allocPixels();
36
37 SkCanvas canvas(device);
38 SkPaint paint;
rmistry@google.comae933ce2012-08-23 18:19:56 +000039
reed@android.com8a1c16f2008-12-17 15:59:43 +000040 paint.setAntiAlias(true);
41 canvas.drawColor(SK_ColorRED);
42 paint.setColor(SK_ColorBLUE);
43 canvas.drawCircle(SkIntToScalar(width)/2, SkIntToScalar(height)/2,
44 SkIntToScalar(width)/2, paint);
45
46 bm->setConfig(config, width, height);
47 switch (config) {
48 case SkBitmap::kARGB_8888_Config:
49 bm->swap(device);
50 break;
51 case SkBitmap::kRGB_565_Config: {
52 bm->allocPixels();
53 for (int y = 0; y < height; y++) {
54 for (int x = 0; x < width; x++) {
55 *bm->getAddr16(x, y) = SkPixel32ToPixel16(*device.getAddr32(x, y));
56 }
57 }
58 break;
59 }
60 case SkBitmap::kIndex8_Config: {
61 SkPMColor colors[256];
62 for (int i = 0; i < 256; i++) {
63 if (configIndex & 1) {
64 colors[i] = SkPackARGB32(255-i, 0, 0, 255-i);
65 } else {
66 colors[i] = SkPackARGB32(0xFF, i, 0, 255-i);
67 }
68 }
69 SkColorTable* ctable = new SkColorTable(colors, 256);
70 bm->allocPixels(ctable);
71 ctable->unref();
rmistry@google.comae933ce2012-08-23 18:19:56 +000072
reed@android.com8a1c16f2008-12-17 15:59:43 +000073 for (int y = 0; y < height; y++) {
74 for (int x = 0; x < width; x++) {
75 *bm->getAddr8(x, y) = SkGetPackedR32(*device.getAddr32(x, y));
76 }
77 }
78 break;
79 }
80 default:
81 break;
82 }
83}
84
85// configs to build the original bitmap in. Can be at most these 3
86static const SkBitmap::Config gConfigs[] = {
87 SkBitmap::kARGB_8888_Config,
88 SkBitmap::kRGB_565_Config,
89 SkBitmap::kIndex8_Config, // opaque
90 SkBitmap::kIndex8_Config // alpha
91};
92
93static const char* const gConfigLabels[] = {
94 "8888", "565", "Index8", "Index8 alpha"
95};
96
97// types to encode into. Can be at most these 3. Must match up with gExt[]
98static const SkImageEncoder::Type gTypes[] = {
99 SkImageEncoder::kJPEG_Type,
100 SkImageEncoder::kPNG_Type
101};
102
103// must match up with gTypes[]
104static const char* const gExt[] = {
105 ".jpg", ".png"
106};
107
reed@android.com8a1c16f2008-12-17 15:59:43 +0000108#include <sys/stat.h>
109
reed@google.com0faac1e2011-05-11 05:58:58 +0000110class EncodeView : public SampleView {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000111public:
halcanary@google.com9acb8cd2014-01-10 14:53:49 +0000112 SkBitmap* fBitmaps;
113 SkAutoDataUnref* fEncodedPNGs;
114 SkAutoDataUnref* fEncodedJPEGs;
reed@google.com7fa2a652014-01-27 13:42:58 +0000115 int fBitmapCount;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000116
rmistry@google.comae933ce2012-08-23 18:19:56 +0000117 EncodeView() {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000118 #if 1
reed@android.com8a1c16f2008-12-17 15:59:43 +0000119 fBitmapCount = SK_ARRAY_COUNT(gConfigs);
120 fBitmaps = new SkBitmap[fBitmapCount];
halcanary@google.com9acb8cd2014-01-10 14:53:49 +0000121 fEncodedPNGs = new SkAutoDataUnref[fBitmapCount];
122 fEncodedJPEGs = new SkAutoDataUnref[fBitmapCount];
reed@google.com7fa2a652014-01-27 13:42:58 +0000123 for (int i = 0; i < fBitmapCount; i++) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000124 make_image(&fBitmaps[i], gConfigs[i], i);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000125
halcanary@google.com9acb8cd2014-01-10 14:53:49 +0000126 for (size_t j = 0; j < SK_ARRAY_COUNT(gTypes); j++) {
127 SkAutoTDelete<SkImageEncoder> codec(
128 SkImageEncoder::Create(gTypes[j]));
129 if (NULL == codec.get()) {
130 SkDebugf("[%s:%d] failed to encode %s%s\n",
131 __FILE__, __LINE__,gConfigLabels[i], gExt[j]);
132 continue;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000133 }
halcanary@google.com9acb8cd2014-01-10 14:53:49 +0000134 SkAutoDataUnref data(codec->encodeData(fBitmaps[i], 100));
135 if (NULL == data.get()) {
136 SkDebugf("[%s:%d] failed to encode %s%s\n",
137 __FILE__, __LINE__,gConfigLabels[i], gExt[j]);
138 continue;
139 }
140 if (SkImageEncoder::kJPEG_Type == gTypes[j]) {
141 fEncodedJPEGs[i].reset(data.detach());
142 } else if (SkImageEncoder::kPNG_Type == gTypes[j]) {
143 fEncodedPNGs[i].reset(data.detach());
144 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000145 }
146 }
147 #else
148 fBitmaps = NULL;
149 fBitmapCount = 0;
150 #endif
reed@google.com0faac1e2011-05-11 05:58:58 +0000151 this->setBGColor(0xFFDDDDDD);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000152 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000153
reed@android.com8a1c16f2008-12-17 15:59:43 +0000154 virtual ~EncodeView() {
155 delete[] fBitmaps;
halcanary@google.com9acb8cd2014-01-10 14:53:49 +0000156 delete[] fEncodedPNGs;
157 delete[] fEncodedJPEGs;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000158 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000159
reed@android.com8a1c16f2008-12-17 15:59:43 +0000160protected:
161 // overrides from SkEventSink
162 virtual bool onQuery(SkEvent* evt) {
163 if (SampleCode::TitleQ(*evt)) {
164 SampleCode::TitleR(evt, "ImageEncoder");
165 return true;
166 }
167 return this->INHERITED::onQuery(evt);
168 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000169
reed@google.com0faac1e2011-05-11 05:58:58 +0000170 virtual void onDrawContent(SkCanvas* canvas) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000171 if (fBitmapCount == 0) {
172 return;
173 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000174
reed@android.com8a1c16f2008-12-17 15:59:43 +0000175 SkPaint paint;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000176 paint.setAntiAlias(true);
177 paint.setTextAlign(SkPaint::kCenter_Align);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000178
reed@android.com8a1c16f2008-12-17 15:59:43 +0000179 canvas->translate(SkIntToScalar(10), SkIntToScalar(20));
rmistry@google.comae933ce2012-08-23 18:19:56 +0000180
reed@android.com8a1c16f2008-12-17 15:59:43 +0000181 SkScalar x = 0, y = 0, maxX = 0;
182 const int SPACER = 10;
rmistry@google.comae933ce2012-08-23 18:19:56 +0000183
reed@google.com7fa2a652014-01-27 13:42:58 +0000184 for (int i = 0; i < fBitmapCount; i++) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000185 canvas->drawText(gConfigLabels[i], strlen(gConfigLabels[i]),
186 x + SkIntToScalar(fBitmaps[i].width()) / 2, 0,
187 paint);
188 y = paint.getTextSize();
189
190 canvas->drawBitmap(fBitmaps[i], x, y);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000191
reed@android.com8a1c16f2008-12-17 15:59:43 +0000192 SkScalar yy = y;
halcanary@google.com9acb8cd2014-01-10 14:53:49 +0000193 for (size_t j = 0; j < SK_ARRAY_COUNT(gTypes); j++) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000194 yy += SkIntToScalar(fBitmaps[i].height() + 10);
195
196 SkBitmap bm;
halcanary@google.com9acb8cd2014-01-10 14:53:49 +0000197 SkData* encoded = NULL;
198 if (SkImageEncoder::kJPEG_Type == gTypes[j]) {
199 encoded = fEncodedJPEGs[i].get();
200 } else if (SkImageEncoder::kPNG_Type == gTypes[j]) {
201 encoded = fEncodedPNGs[i].get();
202 }
203 if (encoded) {
204 if (!SkInstallDiscardablePixelRef(
205 SkDecodingImageGenerator::Create(encoded,
206 SkDecodingImageGenerator::Options()),
207 &bm, NULL)) {
208 SkDebugf("[%s:%d] failed to decode %s%s\n",
209 __FILE__, __LINE__,gConfigLabels[i], gExt[j]);
210 }
211 canvas->drawBitmap(bm, x, yy);
212 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000213 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000214
reed@android.com8a1c16f2008-12-17 15:59:43 +0000215 x += SkIntToScalar(fBitmaps[i].width() + SPACER);
216 if (x > maxX) {
217 maxX = x;
218 }
219 }
220
221 y = (paint.getTextSize() + SkIntToScalar(fBitmaps[0].height())) * 3 / 2;
222 x = maxX + SkIntToScalar(10);
223 paint.setTextAlign(SkPaint::kLeft_Align);
224
225 for (size_t j = 0; j < SK_ARRAY_COUNT(gExt); j++) {
226 canvas->drawText(gExt[j], strlen(gExt[j]), x, y, paint);
227 y += SkIntToScalar(fBitmaps[0].height() + SPACER);
228 }
229 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000230
reed@google.com4d5c26d2013-01-08 16:17:50 +0000231 virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y,
232 unsigned modi) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000233 this->inval(NULL);
reed@google.com4d5c26d2013-01-08 16:17:50 +0000234 return this->INHERITED::onFindClickHandler(x, y, modi);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000235 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000236
reed@android.com8a1c16f2008-12-17 15:59:43 +0000237private:
reed@google.com0faac1e2011-05-11 05:58:58 +0000238 typedef SampleView INHERITED;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000239};
240
241//////////////////////////////////////////////////////////////////////////////
242
243static SkView* MyFactory() { return new EncodeView; }
244static SkViewRegister reg(MyFactory);