blob: e65b2d38554196c1b5fb1f95526e22a57f1b51e9 [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
commit-bot@chromium.orga8c18312014-02-17 02:55:57 +000029static void make_image(SkBitmap* bm, SkColorType ct, int configIndex) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000030 const int width = 98;
31 const int height = 100;
commit-bot@chromium.orga8c18312014-02-17 02:55:57 +000032 const SkImageInfo info = SkImageInfo::Make(width, height, ct, kPremul_SkAlphaType);
33
reed@android.com8a1c16f2008-12-17 15:59:43 +000034 SkBitmap device;
commit-bot@chromium.orga8c18312014-02-17 02:55:57 +000035 device.allocN32Pixels(width, height);
reed@android.com8a1c16f2008-12-17 15:59:43 +000036 SkCanvas canvas(device);
37 SkPaint paint;
rmistry@google.comae933ce2012-08-23 18:19:56 +000038
reed@android.com8a1c16f2008-12-17 15:59:43 +000039 paint.setAntiAlias(true);
40 canvas.drawColor(SK_ColorRED);
41 paint.setColor(SK_ColorBLUE);
42 canvas.drawCircle(SkIntToScalar(width)/2, SkIntToScalar(height)/2,
43 SkIntToScalar(width)/2, paint);
44
commit-bot@chromium.orga8c18312014-02-17 02:55:57 +000045 switch (ct) {
commit-bot@chromium.org28fcae22014-04-11 17:15:40 +000046 case kN32_SkColorType:
reed@android.com8a1c16f2008-12-17 15:59:43 +000047 bm->swap(device);
48 break;
commit-bot@chromium.orga8c18312014-02-17 02:55:57 +000049 case kRGB_565_SkColorType: {
50 bm->allocPixels(info);
reed@android.com8a1c16f2008-12-17 15:59:43 +000051 for (int y = 0; y < height; y++) {
52 for (int x = 0; x < width; x++) {
53 *bm->getAddr16(x, y) = SkPixel32ToPixel16(*device.getAddr32(x, y));
54 }
55 }
56 break;
57 }
commit-bot@chromium.orga8c18312014-02-17 02:55:57 +000058 case kIndex_8_SkColorType: {
reed@android.com8a1c16f2008-12-17 15:59:43 +000059 SkPMColor colors[256];
60 for (int i = 0; i < 256; i++) {
61 if (configIndex & 1) {
62 colors[i] = SkPackARGB32(255-i, 0, 0, 255-i);
63 } else {
64 colors[i] = SkPackARGB32(0xFF, i, 0, 255-i);
65 }
66 }
67 SkColorTable* ctable = new SkColorTable(colors, 256);
commit-bot@chromium.orga8c18312014-02-17 02:55:57 +000068 bm->allocPixels(info, NULL, ctable);
reed@android.com8a1c16f2008-12-17 15:59:43 +000069 ctable->unref();
reed@android.com8a1c16f2008-12-17 15:59:43 +000070 for (int y = 0; y < height; y++) {
71 for (int x = 0; x < width; x++) {
72 *bm->getAddr8(x, y) = SkGetPackedR32(*device.getAddr32(x, y));
73 }
74 }
75 break;
76 }
77 default:
commit-bot@chromium.orga8c18312014-02-17 02:55:57 +000078 SkASSERT(0);
reed@android.com8a1c16f2008-12-17 15:59:43 +000079 }
80}
81
82// configs to build the original bitmap in. Can be at most these 3
commit-bot@chromium.orga8c18312014-02-17 02:55:57 +000083static const SkColorType gColorTypes[] = {
commit-bot@chromium.org28fcae22014-04-11 17:15:40 +000084 kN32_SkColorType,
commit-bot@chromium.orga8c18312014-02-17 02:55:57 +000085 kRGB_565_SkColorType,
86 kIndex_8_SkColorType, // opaque
87 kIndex_8_SkColorType // alpha
reed@android.com8a1c16f2008-12-17 15:59:43 +000088};
89
90static const char* const gConfigLabels[] = {
91 "8888", "565", "Index8", "Index8 alpha"
92};
93
94// types to encode into. Can be at most these 3. Must match up with gExt[]
95static const SkImageEncoder::Type gTypes[] = {
96 SkImageEncoder::kJPEG_Type,
97 SkImageEncoder::kPNG_Type
98};
99
100// must match up with gTypes[]
101static const char* const gExt[] = {
102 ".jpg", ".png"
103};
104
reed@android.com8a1c16f2008-12-17 15:59:43 +0000105#include <sys/stat.h>
106
reed@google.com0faac1e2011-05-11 05:58:58 +0000107class EncodeView : public SampleView {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000108public:
halcanary@google.com9acb8cd2014-01-10 14:53:49 +0000109 SkBitmap* fBitmaps;
110 SkAutoDataUnref* fEncodedPNGs;
111 SkAutoDataUnref* fEncodedJPEGs;
reed@google.com7fa2a652014-01-27 13:42:58 +0000112 int fBitmapCount;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000113
rmistry@google.comae933ce2012-08-23 18:19:56 +0000114 EncodeView() {
commit-bot@chromium.orga8c18312014-02-17 02:55:57 +0000115 fBitmapCount = SK_ARRAY_COUNT(gColorTypes);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000116 fBitmaps = new SkBitmap[fBitmapCount];
halcanary@google.com9acb8cd2014-01-10 14:53:49 +0000117 fEncodedPNGs = new SkAutoDataUnref[fBitmapCount];
118 fEncodedJPEGs = new SkAutoDataUnref[fBitmapCount];
reed@google.com7fa2a652014-01-27 13:42:58 +0000119 for (int i = 0; i < fBitmapCount; i++) {
commit-bot@chromium.orga8c18312014-02-17 02:55:57 +0000120 make_image(&fBitmaps[i], gColorTypes[i], i);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000121
halcanary@google.com9acb8cd2014-01-10 14:53:49 +0000122 for (size_t j = 0; j < SK_ARRAY_COUNT(gTypes); j++) {
123 SkAutoTDelete<SkImageEncoder> codec(
124 SkImageEncoder::Create(gTypes[j]));
125 if (NULL == codec.get()) {
126 SkDebugf("[%s:%d] failed to encode %s%s\n",
127 __FILE__, __LINE__,gConfigLabels[i], gExt[j]);
128 continue;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000129 }
halcanary@google.com9acb8cd2014-01-10 14:53:49 +0000130 SkAutoDataUnref data(codec->encodeData(fBitmaps[i], 100));
131 if (NULL == data.get()) {
132 SkDebugf("[%s:%d] failed to encode %s%s\n",
133 __FILE__, __LINE__,gConfigLabels[i], gExt[j]);
134 continue;
135 }
136 if (SkImageEncoder::kJPEG_Type == gTypes[j]) {
137 fEncodedJPEGs[i].reset(data.detach());
138 } else if (SkImageEncoder::kPNG_Type == gTypes[j]) {
139 fEncodedPNGs[i].reset(data.detach());
140 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000141 }
142 }
reed@google.com0faac1e2011-05-11 05:58:58 +0000143 this->setBGColor(0xFFDDDDDD);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000144 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000145
reed@android.com8a1c16f2008-12-17 15:59:43 +0000146 virtual ~EncodeView() {
147 delete[] fBitmaps;
halcanary@google.com9acb8cd2014-01-10 14:53:49 +0000148 delete[] fEncodedPNGs;
149 delete[] fEncodedJPEGs;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000150 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000151
reed@android.com8a1c16f2008-12-17 15:59:43 +0000152protected:
153 // overrides from SkEventSink
154 virtual bool onQuery(SkEvent* evt) {
155 if (SampleCode::TitleQ(*evt)) {
156 SampleCode::TitleR(evt, "ImageEncoder");
157 return true;
158 }
159 return this->INHERITED::onQuery(evt);
160 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000161
reed@google.com0faac1e2011-05-11 05:58:58 +0000162 virtual void onDrawContent(SkCanvas* canvas) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000163 if (fBitmapCount == 0) {
164 return;
165 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000166
reed@android.com8a1c16f2008-12-17 15:59:43 +0000167 SkPaint paint;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000168 paint.setAntiAlias(true);
169 paint.setTextAlign(SkPaint::kCenter_Align);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000170
reed@android.com8a1c16f2008-12-17 15:59:43 +0000171 canvas->translate(SkIntToScalar(10), SkIntToScalar(20));
rmistry@google.comae933ce2012-08-23 18:19:56 +0000172
reed@android.com8a1c16f2008-12-17 15:59:43 +0000173 SkScalar x = 0, y = 0, maxX = 0;
174 const int SPACER = 10;
rmistry@google.comae933ce2012-08-23 18:19:56 +0000175
reed@google.com7fa2a652014-01-27 13:42:58 +0000176 for (int i = 0; i < fBitmapCount; i++) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000177 canvas->drawText(gConfigLabels[i], strlen(gConfigLabels[i]),
178 x + SkIntToScalar(fBitmaps[i].width()) / 2, 0,
179 paint);
180 y = paint.getTextSize();
181
182 canvas->drawBitmap(fBitmaps[i], x, y);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000183
reed@android.com8a1c16f2008-12-17 15:59:43 +0000184 SkScalar yy = y;
halcanary@google.com9acb8cd2014-01-10 14:53:49 +0000185 for (size_t j = 0; j < SK_ARRAY_COUNT(gTypes); j++) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000186 yy += SkIntToScalar(fBitmaps[i].height() + 10);
187
188 SkBitmap bm;
halcanary@google.com9acb8cd2014-01-10 14:53:49 +0000189 SkData* encoded = NULL;
190 if (SkImageEncoder::kJPEG_Type == gTypes[j]) {
191 encoded = fEncodedJPEGs[i].get();
192 } else if (SkImageEncoder::kPNG_Type == gTypes[j]) {
193 encoded = fEncodedPNGs[i].get();
194 }
195 if (encoded) {
196 if (!SkInstallDiscardablePixelRef(
197 SkDecodingImageGenerator::Create(encoded,
198 SkDecodingImageGenerator::Options()),
commit-bot@chromium.org2d970b52014-05-27 14:14:22 +0000199 &bm)) {
halcanary@google.com9acb8cd2014-01-10 14:53:49 +0000200 SkDebugf("[%s:%d] failed to decode %s%s\n",
201 __FILE__, __LINE__,gConfigLabels[i], gExt[j]);
202 }
203 canvas->drawBitmap(bm, x, yy);
204 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000205 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000206
reed@android.com8a1c16f2008-12-17 15:59:43 +0000207 x += SkIntToScalar(fBitmaps[i].width() + SPACER);
208 if (x > maxX) {
209 maxX = x;
210 }
211 }
212
213 y = (paint.getTextSize() + SkIntToScalar(fBitmaps[0].height())) * 3 / 2;
214 x = maxX + SkIntToScalar(10);
215 paint.setTextAlign(SkPaint::kLeft_Align);
216
217 for (size_t j = 0; j < SK_ARRAY_COUNT(gExt); j++) {
218 canvas->drawText(gExt[j], strlen(gExt[j]), x, y, paint);
219 y += SkIntToScalar(fBitmaps[0].height() + SPACER);
220 }
221 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000222
reed@google.com4d5c26d2013-01-08 16:17:50 +0000223 virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y,
224 unsigned modi) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000225 this->inval(NULL);
reed@google.com4d5c26d2013-01-08 16:17:50 +0000226 return this->INHERITED::onFindClickHandler(x, y, modi);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000227 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000228
reed@android.com8a1c16f2008-12-17 15:59:43 +0000229private:
reed@google.com0faac1e2011-05-11 05:58:58 +0000230 typedef SampleView INHERITED;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000231};
232
233//////////////////////////////////////////////////////////////////////////////
234
235static SkView* MyFactory() { return new EncodeView; }
236static SkViewRegister reg(MyFactory);