SkPngCodec.cpp 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194
  1. /*
  2. * Copyright 2015 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "include/core/SkBitmap.h"
  8. #include "include/core/SkColorSpace.h"
  9. #include "include/core/SkMath.h"
  10. #include "include/core/SkPoint3.h"
  11. #include "include/core/SkSize.h"
  12. #include "include/core/SkStream.h"
  13. #include "include/private/SkColorData.h"
  14. #include "include/private/SkMacros.h"
  15. #include "include/private/SkTemplates.h"
  16. #include "src/codec/SkCodecPriv.h"
  17. #include "src/codec/SkColorTable.h"
  18. #include "src/codec/SkPngCodec.h"
  19. #include "src/codec/SkPngPriv.h"
  20. #include "src/codec/SkSwizzler.h"
  21. #include "src/core/SkOpts.h"
  22. #include "src/core/SkUtils.h"
  23. #include "png.h"
  24. #include <algorithm>
  25. #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
  26. #include "include/android/SkAndroidFrameworkUtils.h"
  27. #endif
  28. // This warning triggers false postives way too often in here.
  29. #if defined(__GNUC__) && !defined(__clang__)
  30. #pragma GCC diagnostic ignored "-Wclobbered"
  31. #endif
  32. // FIXME (scroggo): We can use png_jumpbuf directly once Google3 is on 1.6
  33. #define PNG_JMPBUF(x) png_jmpbuf((png_structp) x)
  34. ///////////////////////////////////////////////////////////////////////////////
  35. // Callback functions
  36. ///////////////////////////////////////////////////////////////////////////////
  37. // When setjmp is first called, it returns 0, meaning longjmp was not called.
  38. constexpr int kSetJmpOkay = 0;
  39. // An error internal to libpng.
  40. constexpr int kPngError = 1;
  41. // Passed to longjmp when we have decoded as many lines as we need.
  42. constexpr int kStopDecoding = 2;
  43. static void sk_error_fn(png_structp png_ptr, png_const_charp msg) {
  44. SkCodecPrintf("------ png error %s\n", msg);
  45. longjmp(PNG_JMPBUF(png_ptr), kPngError);
  46. }
  47. void sk_warning_fn(png_structp, png_const_charp msg) {
  48. SkCodecPrintf("----- png warning %s\n", msg);
  49. }
  50. #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
  51. static int sk_read_user_chunk(png_structp png_ptr, png_unknown_chunkp chunk) {
  52. SkPngChunkReader* chunkReader = (SkPngChunkReader*)png_get_user_chunk_ptr(png_ptr);
  53. // readChunk() returning true means continue decoding
  54. return chunkReader->readChunk((const char*)chunk->name, chunk->data, chunk->size) ? 1 : -1;
  55. }
  56. #endif
  57. ///////////////////////////////////////////////////////////////////////////////
  58. // Helpers
  59. ///////////////////////////////////////////////////////////////////////////////
  60. class AutoCleanPng : public SkNoncopyable {
  61. public:
  62. /*
  63. * This class does not take ownership of stream or reader, but if codecPtr
  64. * is non-NULL, and decodeBounds succeeds, it will have created a new
  65. * SkCodec (pointed to by *codecPtr) which will own/ref them, as well as
  66. * the png_ptr and info_ptr.
  67. */
  68. AutoCleanPng(png_structp png_ptr, SkStream* stream, SkPngChunkReader* reader,
  69. SkCodec** codecPtr)
  70. : fPng_ptr(png_ptr)
  71. , fInfo_ptr(nullptr)
  72. , fStream(stream)
  73. , fChunkReader(reader)
  74. , fOutCodec(codecPtr)
  75. {}
  76. ~AutoCleanPng() {
  77. // fInfo_ptr will never be non-nullptr unless fPng_ptr is.
  78. if (fPng_ptr) {
  79. png_infopp info_pp = fInfo_ptr ? &fInfo_ptr : nullptr;
  80. png_destroy_read_struct(&fPng_ptr, info_pp, nullptr);
  81. }
  82. }
  83. void setInfoPtr(png_infop info_ptr) {
  84. SkASSERT(nullptr == fInfo_ptr);
  85. fInfo_ptr = info_ptr;
  86. }
  87. /**
  88. * Reads enough of the input stream to decode the bounds.
  89. * @return false if the stream is not a valid PNG (or too short).
  90. * true if it read enough of the stream to determine the bounds.
  91. * In the latter case, the stream may have been read beyond the
  92. * point to determine the bounds, and the png_ptr will have saved
  93. * any extra data. Further, if the codecPtr supplied to the
  94. * constructor was not NULL, it will now point to a new SkCodec,
  95. * which owns (or refs, in the case of the SkPngChunkReader) the
  96. * inputs. If codecPtr was NULL, the png_ptr and info_ptr are
  97. * unowned, and it is up to the caller to destroy them.
  98. */
  99. bool decodeBounds();
  100. private:
  101. png_structp fPng_ptr;
  102. png_infop fInfo_ptr;
  103. SkStream* fStream;
  104. SkPngChunkReader* fChunkReader;
  105. SkCodec** fOutCodec;
  106. void infoCallback(size_t idatLength);
  107. void releasePngPtrs() {
  108. fPng_ptr = nullptr;
  109. fInfo_ptr = nullptr;
  110. }
  111. };
  112. #define AutoCleanPng(...) SK_REQUIRE_LOCAL_VAR(AutoCleanPng)
  113. static inline bool is_chunk(const png_byte* chunk, const char* tag) {
  114. return memcmp(chunk + 4, tag, 4) == 0;
  115. }
  116. static inline bool process_data(png_structp png_ptr, png_infop info_ptr,
  117. SkStream* stream, void* buffer, size_t bufferSize, size_t length) {
  118. while (length > 0) {
  119. const size_t bytesToProcess = std::min(bufferSize, length);
  120. const size_t bytesRead = stream->read(buffer, bytesToProcess);
  121. png_process_data(png_ptr, info_ptr, (png_bytep) buffer, bytesRead);
  122. if (bytesRead < bytesToProcess) {
  123. return false;
  124. }
  125. length -= bytesToProcess;
  126. }
  127. return true;
  128. }
  129. bool AutoCleanPng::decodeBounds() {
  130. if (setjmp(PNG_JMPBUF(fPng_ptr))) {
  131. return false;
  132. }
  133. png_set_progressive_read_fn(fPng_ptr, nullptr, nullptr, nullptr, nullptr);
  134. // Arbitrary buffer size, though note that it matches (below)
  135. // SkPngCodec::processData(). FIXME: Can we better suit this to the size of
  136. // the PNG header?
  137. constexpr size_t kBufferSize = 4096;
  138. char buffer[kBufferSize];
  139. {
  140. // Parse the signature.
  141. if (fStream->read(buffer, 8) < 8) {
  142. return false;
  143. }
  144. png_process_data(fPng_ptr, fInfo_ptr, (png_bytep) buffer, 8);
  145. }
  146. while (true) {
  147. // Parse chunk length and type.
  148. if (fStream->read(buffer, 8) < 8) {
  149. // We have read to the end of the input without decoding bounds.
  150. break;
  151. }
  152. png_byte* chunk = reinterpret_cast<png_byte*>(buffer);
  153. const size_t length = png_get_uint_32(chunk);
  154. if (is_chunk(chunk, "IDAT")) {
  155. this->infoCallback(length);
  156. return true;
  157. }
  158. png_process_data(fPng_ptr, fInfo_ptr, chunk, 8);
  159. // Process the full chunk + CRC.
  160. if (!process_data(fPng_ptr, fInfo_ptr, fStream, buffer, kBufferSize, length + 4)) {
  161. return false;
  162. }
  163. }
  164. return false;
  165. }
  166. bool SkPngCodec::processData() {
  167. switch (setjmp(PNG_JMPBUF(fPng_ptr))) {
  168. case kPngError:
  169. // There was an error. Stop processing data.
  170. // FIXME: Do we need to discard png_ptr?
  171. return false;
  172. case kStopDecoding:
  173. // We decoded all the lines we want.
  174. return true;
  175. case kSetJmpOkay:
  176. // Everything is okay.
  177. break;
  178. default:
  179. // No other values should be passed to longjmp.
  180. SkASSERT(false);
  181. }
  182. // Arbitrary buffer size
  183. constexpr size_t kBufferSize = 4096;
  184. char buffer[kBufferSize];
  185. bool iend = false;
  186. while (true) {
  187. size_t length;
  188. if (fDecodedIdat) {
  189. // Parse chunk length and type.
  190. if (this->stream()->read(buffer, 8) < 8) {
  191. break;
  192. }
  193. png_byte* chunk = reinterpret_cast<png_byte*>(buffer);
  194. png_process_data(fPng_ptr, fInfo_ptr, chunk, 8);
  195. if (is_chunk(chunk, "IEND")) {
  196. iend = true;
  197. }
  198. length = png_get_uint_32(chunk);
  199. } else {
  200. length = fIdatLength;
  201. png_byte idat[] = {0, 0, 0, 0, 'I', 'D', 'A', 'T'};
  202. png_save_uint_32(idat, length);
  203. png_process_data(fPng_ptr, fInfo_ptr, idat, 8);
  204. fDecodedIdat = true;
  205. }
  206. // Process the full chunk + CRC.
  207. if (!process_data(fPng_ptr, fInfo_ptr, this->stream(), buffer, kBufferSize, length + 4)
  208. || iend) {
  209. break;
  210. }
  211. }
  212. return true;
  213. }
  214. static constexpr SkColorType kXformSrcColorType = kRGBA_8888_SkColorType;
  215. static inline bool needs_premul(SkAlphaType dstAT, SkEncodedInfo::Alpha encodedAlpha) {
  216. return kPremul_SkAlphaType == dstAT && SkEncodedInfo::kUnpremul_Alpha == encodedAlpha;
  217. }
  218. // Note: SkColorTable claims to store SkPMColors, which is not necessarily the case here.
  219. bool SkPngCodec::createColorTable(const SkImageInfo& dstInfo) {
  220. int numColors;
  221. png_color* palette;
  222. if (!png_get_PLTE(fPng_ptr, fInfo_ptr, &palette, &numColors)) {
  223. return false;
  224. }
  225. // Contents depend on tableColorType and our choice of if/when to premultiply:
  226. // { kPremul, kUnpremul, kOpaque } x { RGBA, BGRA }
  227. SkPMColor colorTable[256];
  228. SkColorType tableColorType = this->colorXform() ? kXformSrcColorType : dstInfo.colorType();
  229. png_bytep alphas;
  230. int numColorsWithAlpha = 0;
  231. if (png_get_tRNS(fPng_ptr, fInfo_ptr, &alphas, &numColorsWithAlpha, nullptr)) {
  232. bool premultiply = needs_premul(dstInfo.alphaType(), this->getEncodedInfo().alpha());
  233. // Choose which function to use to create the color table. If the final destination's
  234. // colortype is unpremultiplied, the color table will store unpremultiplied colors.
  235. PackColorProc proc = choose_pack_color_proc(premultiply, tableColorType);
  236. for (int i = 0; i < numColorsWithAlpha; i++) {
  237. // We don't have a function in SkOpts that combines a set of alphas with a set
  238. // of RGBs. We could write one, but it's hardly worth it, given that this
  239. // is such a small fraction of the total decode time.
  240. colorTable[i] = proc(alphas[i], palette->red, palette->green, palette->blue);
  241. palette++;
  242. }
  243. }
  244. if (numColorsWithAlpha < numColors) {
  245. // The optimized code depends on a 3-byte png_color struct with the colors
  246. // in RGB order. These checks make sure it is safe to use.
  247. static_assert(3 == sizeof(png_color), "png_color struct has changed. Opts are broken.");
  248. #ifdef SK_DEBUG
  249. SkASSERT(&palette->red < &palette->green);
  250. SkASSERT(&palette->green < &palette->blue);
  251. #endif
  252. if (is_rgba(tableColorType)) {
  253. SkOpts::RGB_to_RGB1(colorTable + numColorsWithAlpha, (const uint8_t*)palette,
  254. numColors - numColorsWithAlpha);
  255. } else {
  256. SkOpts::RGB_to_BGR1(colorTable + numColorsWithAlpha, (const uint8_t*)palette,
  257. numColors - numColorsWithAlpha);
  258. }
  259. }
  260. if (this->colorXform() && !this->xformOnDecode()) {
  261. this->applyColorXform(colorTable, colorTable, numColors);
  262. }
  263. // Pad the color table with the last color in the table (or black) in the case that
  264. // invalid pixel indices exceed the number of colors in the table.
  265. const int maxColors = 1 << fBitDepth;
  266. if (numColors < maxColors) {
  267. SkPMColor lastColor = numColors > 0 ? colorTable[numColors - 1] : SK_ColorBLACK;
  268. sk_memset32(colorTable + numColors, lastColor, maxColors - numColors);
  269. }
  270. fColorTable.reset(new SkColorTable(colorTable, maxColors));
  271. return true;
  272. }
  273. ///////////////////////////////////////////////////////////////////////////////
  274. // Creation
  275. ///////////////////////////////////////////////////////////////////////////////
  276. bool SkPngCodec::IsPng(const char* buf, size_t bytesRead) {
  277. return !png_sig_cmp((png_bytep) buf, (png_size_t)0, bytesRead);
  278. }
  279. #if (PNG_LIBPNG_VER_MAJOR > 1) || (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR >= 6)
  280. static float png_fixed_point_to_float(png_fixed_point x) {
  281. // We multiply by the same factor that libpng used to convert
  282. // fixed point -> double. Since we want floats, we choose to
  283. // do the conversion ourselves rather than convert
  284. // fixed point -> double -> float.
  285. return ((float) x) * 0.00001f;
  286. }
  287. static float png_inverted_fixed_point_to_float(png_fixed_point x) {
  288. // This is necessary because the gAMA chunk actually stores 1/gamma.
  289. return 1.0f / png_fixed_point_to_float(x);
  290. }
  291. #endif // LIBPNG >= 1.6
  292. // If there is no color profile information, it will use sRGB.
  293. std::unique_ptr<SkEncodedInfo::ICCProfile> read_color_profile(png_structp png_ptr,
  294. png_infop info_ptr) {
  295. #if (PNG_LIBPNG_VER_MAJOR > 1) || (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR >= 6)
  296. // First check for an ICC profile
  297. png_bytep profile;
  298. png_uint_32 length;
  299. // The below variables are unused, however, we need to pass them in anyway or
  300. // png_get_iCCP() will return nothing.
  301. // Could knowing the |name| of the profile ever be interesting? Maybe for debugging?
  302. png_charp name;
  303. // The |compression| is uninteresting since:
  304. // (1) libpng has already decompressed the profile for us.
  305. // (2) "deflate" is the only mode of decompression that libpng supports.
  306. int compression;
  307. if (PNG_INFO_iCCP == png_get_iCCP(png_ptr, info_ptr, &name, &compression, &profile,
  308. &length)) {
  309. auto data = SkData::MakeWithCopy(profile, length);
  310. return SkEncodedInfo::ICCProfile::Make(std::move(data));
  311. }
  312. // Second, check for sRGB.
  313. // Note that Blink does this first. This code checks ICC first, with the thinking that
  314. // an image has both truly wants the potentially more specific ICC chunk, with sRGB as a
  315. // backup in case the decoder does not support full color management.
  316. if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sRGB)) {
  317. // sRGB chunks also store a rendering intent: Absolute, Relative,
  318. // Perceptual, and Saturation.
  319. // FIXME (scroggo): Extract this information from the sRGB chunk once
  320. // we are able to handle this information in
  321. // skcms_ICCProfile
  322. return nullptr;
  323. }
  324. // Default to SRGB gamut.
  325. skcms_Matrix3x3 toXYZD50 = skcms_sRGB_profile()->toXYZD50;
  326. // Next, check for chromaticities.
  327. png_fixed_point chrm[8];
  328. png_fixed_point gamma;
  329. if (png_get_cHRM_fixed(png_ptr, info_ptr, &chrm[0], &chrm[1], &chrm[2], &chrm[3], &chrm[4],
  330. &chrm[5], &chrm[6], &chrm[7]))
  331. {
  332. float rx = png_fixed_point_to_float(chrm[2]);
  333. float ry = png_fixed_point_to_float(chrm[3]);
  334. float gx = png_fixed_point_to_float(chrm[4]);
  335. float gy = png_fixed_point_to_float(chrm[5]);
  336. float bx = png_fixed_point_to_float(chrm[6]);
  337. float by = png_fixed_point_to_float(chrm[7]);
  338. float wx = png_fixed_point_to_float(chrm[0]);
  339. float wy = png_fixed_point_to_float(chrm[1]);
  340. skcms_Matrix3x3 tmp;
  341. if (skcms_PrimariesToXYZD50(rx, ry, gx, gy, bx, by, wx, wy, &tmp)) {
  342. toXYZD50 = tmp;
  343. } else {
  344. // Note that Blink simply returns nullptr in this case. We'll fall
  345. // back to srgb.
  346. }
  347. }
  348. skcms_TransferFunction fn;
  349. if (PNG_INFO_gAMA == png_get_gAMA_fixed(png_ptr, info_ptr, &gamma)) {
  350. fn.a = 1.0f;
  351. fn.b = fn.c = fn.d = fn.e = fn.f = 0.0f;
  352. fn.g = png_inverted_fixed_point_to_float(gamma);
  353. } else {
  354. // Default to sRGB gamma if the image has color space information,
  355. // but does not specify gamma.
  356. // Note that Blink would again return nullptr in this case.
  357. fn = *skcms_sRGB_TransferFunction();
  358. }
  359. skcms_ICCProfile skcmsProfile;
  360. skcms_Init(&skcmsProfile);
  361. skcms_SetTransferFunction(&skcmsProfile, &fn);
  362. skcms_SetXYZD50(&skcmsProfile, &toXYZD50);
  363. return SkEncodedInfo::ICCProfile::Make(skcmsProfile);
  364. #else // LIBPNG >= 1.6
  365. return nullptr;
  366. #endif // LIBPNG >= 1.6
  367. }
  368. void SkPngCodec::allocateStorage(const SkImageInfo& dstInfo) {
  369. switch (fXformMode) {
  370. case kSwizzleOnly_XformMode:
  371. break;
  372. case kColorOnly_XformMode:
  373. // Intentional fall through. A swizzler hasn't been created yet, but one will
  374. // be created later if we are sampling. We'll go ahead and allocate
  375. // enough memory to swizzle if necessary.
  376. case kSwizzleColor_XformMode: {
  377. const int bitsPerPixel = this->getEncodedInfo().bitsPerPixel();
  378. // If we have more than 8-bits (per component) of precision, we will keep that
  379. // extra precision. Otherwise, we will swizzle to RGBA_8888 before transforming.
  380. const size_t bytesPerPixel = (bitsPerPixel > 32) ? bitsPerPixel / 8 : 4;
  381. const size_t colorXformBytes = dstInfo.width() * bytesPerPixel;
  382. fStorage.reset(colorXformBytes);
  383. fColorXformSrcRow = fStorage.get();
  384. break;
  385. }
  386. }
  387. }
  388. static skcms_PixelFormat png_select_xform_format(const SkEncodedInfo& info) {
  389. // We use kRGB and kRGBA formats because color PNGs are always RGB or RGBA.
  390. if (16 == info.bitsPerComponent()) {
  391. if (SkEncodedInfo::kRGBA_Color == info.color()) {
  392. return skcms_PixelFormat_RGBA_16161616BE;
  393. } else if (SkEncodedInfo::kRGB_Color == info.color()) {
  394. return skcms_PixelFormat_RGB_161616BE;
  395. }
  396. } else if (SkEncodedInfo::kGray_Color == info.color()) {
  397. return skcms_PixelFormat_G_8;
  398. }
  399. return skcms_PixelFormat_RGBA_8888;
  400. }
  401. void SkPngCodec::applyXformRow(void* dst, const void* src) {
  402. switch (fXformMode) {
  403. case kSwizzleOnly_XformMode:
  404. fSwizzler->swizzle(dst, (const uint8_t*) src);
  405. break;
  406. case kColorOnly_XformMode:
  407. this->applyColorXform(dst, src, fXformWidth);
  408. break;
  409. case kSwizzleColor_XformMode:
  410. fSwizzler->swizzle(fColorXformSrcRow, (const uint8_t*) src);
  411. this->applyColorXform(dst, fColorXformSrcRow, fXformWidth);
  412. break;
  413. }
  414. }
  415. static SkCodec::Result log_and_return_error(bool success) {
  416. if (success) return SkCodec::kIncompleteInput;
  417. #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
  418. SkAndroidFrameworkUtils::SafetyNetLog("117838472");
  419. #endif
  420. return SkCodec::kErrorInInput;
  421. }
  422. class SkPngNormalDecoder : public SkPngCodec {
  423. public:
  424. SkPngNormalDecoder(SkEncodedInfo&& info, std::unique_ptr<SkStream> stream,
  425. SkPngChunkReader* reader, png_structp png_ptr, png_infop info_ptr, int bitDepth)
  426. : INHERITED(std::move(info), std::move(stream), reader, png_ptr, info_ptr, bitDepth)
  427. , fRowsWrittenToOutput(0)
  428. , fDst(nullptr)
  429. , fRowBytes(0)
  430. , fFirstRow(0)
  431. , fLastRow(0)
  432. {}
  433. static void AllRowsCallback(png_structp png_ptr, png_bytep row, png_uint_32 rowNum, int /*pass*/) {
  434. GetDecoder(png_ptr)->allRowsCallback(row, rowNum);
  435. }
  436. static void RowCallback(png_structp png_ptr, png_bytep row, png_uint_32 rowNum, int /*pass*/) {
  437. GetDecoder(png_ptr)->rowCallback(row, rowNum);
  438. }
  439. private:
  440. int fRowsWrittenToOutput;
  441. void* fDst;
  442. size_t fRowBytes;
  443. // Variables for partial decode
  444. int fFirstRow; // FIXME: Move to baseclass?
  445. int fLastRow;
  446. int fRowsNeeded;
  447. typedef SkPngCodec INHERITED;
  448. static SkPngNormalDecoder* GetDecoder(png_structp png_ptr) {
  449. return static_cast<SkPngNormalDecoder*>(png_get_progressive_ptr(png_ptr));
  450. }
  451. Result decodeAllRows(void* dst, size_t rowBytes, int* rowsDecoded) override {
  452. const int height = this->dimensions().height();
  453. png_set_progressive_read_fn(this->png_ptr(), this, nullptr, AllRowsCallback, nullptr);
  454. fDst = dst;
  455. fRowBytes = rowBytes;
  456. fRowsWrittenToOutput = 0;
  457. fFirstRow = 0;
  458. fLastRow = height - 1;
  459. const bool success = this->processData();
  460. if (success && fRowsWrittenToOutput == height) {
  461. return kSuccess;
  462. }
  463. if (rowsDecoded) {
  464. *rowsDecoded = fRowsWrittenToOutput;
  465. }
  466. return log_and_return_error(success);
  467. }
  468. void allRowsCallback(png_bytep row, int rowNum) {
  469. SkASSERT(rowNum == fRowsWrittenToOutput);
  470. fRowsWrittenToOutput++;
  471. this->applyXformRow(fDst, row);
  472. fDst = SkTAddOffset<void>(fDst, fRowBytes);
  473. }
  474. void setRange(int firstRow, int lastRow, void* dst, size_t rowBytes) override {
  475. png_set_progressive_read_fn(this->png_ptr(), this, nullptr, RowCallback, nullptr);
  476. fFirstRow = firstRow;
  477. fLastRow = lastRow;
  478. fDst = dst;
  479. fRowBytes = rowBytes;
  480. fRowsWrittenToOutput = 0;
  481. fRowsNeeded = fLastRow - fFirstRow + 1;
  482. }
  483. Result decode(int* rowsDecoded) override {
  484. if (this->swizzler()) {
  485. const int sampleY = this->swizzler()->sampleY();
  486. fRowsNeeded = get_scaled_dimension(fLastRow - fFirstRow + 1, sampleY);
  487. }
  488. const bool success = this->processData();
  489. if (success && fRowsWrittenToOutput == fRowsNeeded) {
  490. return kSuccess;
  491. }
  492. if (rowsDecoded) {
  493. *rowsDecoded = fRowsWrittenToOutput;
  494. }
  495. return log_and_return_error(success);
  496. }
  497. void rowCallback(png_bytep row, int rowNum) {
  498. if (rowNum < fFirstRow) {
  499. // Ignore this row.
  500. return;
  501. }
  502. SkASSERT(rowNum <= fLastRow);
  503. SkASSERT(fRowsWrittenToOutput < fRowsNeeded);
  504. // If there is no swizzler, all rows are needed.
  505. if (!this->swizzler() || this->swizzler()->rowNeeded(rowNum - fFirstRow)) {
  506. this->applyXformRow(fDst, row);
  507. fDst = SkTAddOffset<void>(fDst, fRowBytes);
  508. fRowsWrittenToOutput++;
  509. }
  510. if (fRowsWrittenToOutput == fRowsNeeded) {
  511. // Fake error to stop decoding scanlines.
  512. longjmp(PNG_JMPBUF(this->png_ptr()), kStopDecoding);
  513. }
  514. }
  515. };
  516. class SkPngInterlacedDecoder : public SkPngCodec {
  517. public:
  518. SkPngInterlacedDecoder(SkEncodedInfo&& info, std::unique_ptr<SkStream> stream,
  519. SkPngChunkReader* reader, png_structp png_ptr,
  520. png_infop info_ptr, int bitDepth, int numberPasses)
  521. : INHERITED(std::move(info), std::move(stream), reader, png_ptr, info_ptr, bitDepth)
  522. , fNumberPasses(numberPasses)
  523. , fFirstRow(0)
  524. , fLastRow(0)
  525. , fLinesDecoded(0)
  526. , fInterlacedComplete(false)
  527. , fPng_rowbytes(0)
  528. {}
  529. static void InterlacedRowCallback(png_structp png_ptr, png_bytep row, png_uint_32 rowNum, int pass) {
  530. auto decoder = static_cast<SkPngInterlacedDecoder*>(png_get_progressive_ptr(png_ptr));
  531. decoder->interlacedRowCallback(row, rowNum, pass);
  532. }
  533. private:
  534. const int fNumberPasses;
  535. int fFirstRow;
  536. int fLastRow;
  537. void* fDst;
  538. size_t fRowBytes;
  539. int fLinesDecoded;
  540. bool fInterlacedComplete;
  541. size_t fPng_rowbytes;
  542. SkAutoTMalloc<png_byte> fInterlaceBuffer;
  543. typedef SkPngCodec INHERITED;
  544. // FIXME: Currently sharing interlaced callback for all rows and subset. It's not
  545. // as expensive as the subset version of non-interlaced, but it still does extra
  546. // work.
  547. void interlacedRowCallback(png_bytep row, int rowNum, int pass) {
  548. if (rowNum < fFirstRow || rowNum > fLastRow || fInterlacedComplete) {
  549. // Ignore this row
  550. return;
  551. }
  552. png_bytep oldRow = fInterlaceBuffer.get() + (rowNum - fFirstRow) * fPng_rowbytes;
  553. png_progressive_combine_row(this->png_ptr(), oldRow, row);
  554. if (0 == pass) {
  555. // The first pass initializes all rows.
  556. SkASSERT(row);
  557. SkASSERT(fLinesDecoded == rowNum - fFirstRow);
  558. fLinesDecoded++;
  559. } else {
  560. SkASSERT(fLinesDecoded == fLastRow - fFirstRow + 1);
  561. if (fNumberPasses - 1 == pass && rowNum == fLastRow) {
  562. // Last pass, and we have read all of the rows we care about.
  563. fInterlacedComplete = true;
  564. if (fLastRow != this->dimensions().height() - 1 ||
  565. (this->swizzler() && this->swizzler()->sampleY() != 1)) {
  566. // Fake error to stop decoding scanlines. Only stop if we're not decoding the
  567. // whole image, in which case processing the rest of the image might be
  568. // expensive. When decoding the whole image, read through the IEND chunk to
  569. // preserve Android behavior of leaving the input stream in the right place.
  570. longjmp(PNG_JMPBUF(this->png_ptr()), kStopDecoding);
  571. }
  572. }
  573. }
  574. }
  575. Result decodeAllRows(void* dst, size_t rowBytes, int* rowsDecoded) override {
  576. const int height = this->dimensions().height();
  577. this->setUpInterlaceBuffer(height);
  578. png_set_progressive_read_fn(this->png_ptr(), this, nullptr, InterlacedRowCallback,
  579. nullptr);
  580. fFirstRow = 0;
  581. fLastRow = height - 1;
  582. fLinesDecoded = 0;
  583. const bool success = this->processData();
  584. png_bytep srcRow = fInterlaceBuffer.get();
  585. // FIXME: When resuming, this may rewrite rows that did not change.
  586. for (int rowNum = 0; rowNum < fLinesDecoded; rowNum++) {
  587. this->applyXformRow(dst, srcRow);
  588. dst = SkTAddOffset<void>(dst, rowBytes);
  589. srcRow = SkTAddOffset<png_byte>(srcRow, fPng_rowbytes);
  590. }
  591. if (success && fInterlacedComplete) {
  592. return kSuccess;
  593. }
  594. if (rowsDecoded) {
  595. *rowsDecoded = fLinesDecoded;
  596. }
  597. return log_and_return_error(success);
  598. }
  599. void setRange(int firstRow, int lastRow, void* dst, size_t rowBytes) override {
  600. // FIXME: We could skip rows in the interlace buffer that we won't put in the output.
  601. this->setUpInterlaceBuffer(lastRow - firstRow + 1);
  602. png_set_progressive_read_fn(this->png_ptr(), this, nullptr, InterlacedRowCallback, nullptr);
  603. fFirstRow = firstRow;
  604. fLastRow = lastRow;
  605. fDst = dst;
  606. fRowBytes = rowBytes;
  607. fLinesDecoded = 0;
  608. }
  609. Result decode(int* rowsDecoded) override {
  610. const bool success = this->processData();
  611. // Now apply Xforms on all the rows that were decoded.
  612. if (!fLinesDecoded) {
  613. if (rowsDecoded) {
  614. *rowsDecoded = 0;
  615. }
  616. return log_and_return_error(success);
  617. }
  618. const int sampleY = this->swizzler() ? this->swizzler()->sampleY() : 1;
  619. const int rowsNeeded = get_scaled_dimension(fLastRow - fFirstRow + 1, sampleY);
  620. // FIXME: For resuming interlace, we may swizzle a row that hasn't changed. But it
  621. // may be too tricky/expensive to handle that correctly.
  622. // Offset srcRow by get_start_coord rows. We do not need to account for fFirstRow,
  623. // since the first row in fInterlaceBuffer corresponds to fFirstRow.
  624. int srcRow = get_start_coord(sampleY);
  625. void* dst = fDst;
  626. int rowsWrittenToOutput = 0;
  627. while (rowsWrittenToOutput < rowsNeeded && srcRow < fLinesDecoded) {
  628. png_bytep src = SkTAddOffset<png_byte>(fInterlaceBuffer.get(), fPng_rowbytes * srcRow);
  629. this->applyXformRow(dst, src);
  630. dst = SkTAddOffset<void>(dst, fRowBytes);
  631. rowsWrittenToOutput++;
  632. srcRow += sampleY;
  633. }
  634. if (success && fInterlacedComplete) {
  635. return kSuccess;
  636. }
  637. if (rowsDecoded) {
  638. *rowsDecoded = rowsWrittenToOutput;
  639. }
  640. return log_and_return_error(success);
  641. }
  642. void setUpInterlaceBuffer(int height) {
  643. fPng_rowbytes = png_get_rowbytes(this->png_ptr(), this->info_ptr());
  644. fInterlaceBuffer.reset(fPng_rowbytes * height);
  645. fInterlacedComplete = false;
  646. }
  647. };
  648. // Reads the header and initializes the output fields, if not NULL.
  649. //
  650. // @param stream Input data. Will be read to get enough information to properly
  651. // setup the codec.
  652. // @param chunkReader SkPngChunkReader, for reading unknown chunks. May be NULL.
  653. // If not NULL, png_ptr will hold an *unowned* pointer to it. The caller is
  654. // expected to continue to own it for the lifetime of the png_ptr.
  655. // @param outCodec Optional output variable. If non-NULL, will be set to a new
  656. // SkPngCodec on success.
  657. // @param png_ptrp Optional output variable. If non-NULL, will be set to a new
  658. // png_structp on success.
  659. // @param info_ptrp Optional output variable. If non-NULL, will be set to a new
  660. // png_infop on success;
  661. // @return if kSuccess, the caller is responsible for calling
  662. // png_destroy_read_struct(png_ptrp, info_ptrp).
  663. // Otherwise, the passed in fields (except stream) are unchanged.
  664. static SkCodec::Result read_header(SkStream* stream, SkPngChunkReader* chunkReader,
  665. SkCodec** outCodec,
  666. png_structp* png_ptrp, png_infop* info_ptrp) {
  667. // The image is known to be a PNG. Decode enough to know the SkImageInfo.
  668. png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr,
  669. sk_error_fn, sk_warning_fn);
  670. if (!png_ptr) {
  671. return SkCodec::kInternalError;
  672. }
  673. #ifdef PNG_SET_OPTION_SUPPORTED
  674. // This setting ensures that we display images with incorrect CMF bytes.
  675. // See crbug.com/807324.
  676. png_set_option(png_ptr, PNG_MAXIMUM_INFLATE_WINDOW, PNG_OPTION_ON);
  677. #endif
  678. AutoCleanPng autoClean(png_ptr, stream, chunkReader, outCodec);
  679. png_infop info_ptr = png_create_info_struct(png_ptr);
  680. if (info_ptr == nullptr) {
  681. return SkCodec::kInternalError;
  682. }
  683. autoClean.setInfoPtr(info_ptr);
  684. if (setjmp(PNG_JMPBUF(png_ptr))) {
  685. return SkCodec::kInvalidInput;
  686. }
  687. #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
  688. // Hookup our chunkReader so we can see any user-chunks the caller may be interested in.
  689. // This needs to be installed before we read the png header. Android may store ninepatch
  690. // chunks in the header.
  691. if (chunkReader) {
  692. png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_ALWAYS, (png_byte*)"", 0);
  693. png_set_read_user_chunk_fn(png_ptr, (png_voidp) chunkReader, sk_read_user_chunk);
  694. }
  695. #endif
  696. const bool decodedBounds = autoClean.decodeBounds();
  697. if (!decodedBounds) {
  698. return SkCodec::kIncompleteInput;
  699. }
  700. // On success, decodeBounds releases ownership of png_ptr and info_ptr.
  701. if (png_ptrp) {
  702. *png_ptrp = png_ptr;
  703. }
  704. if (info_ptrp) {
  705. *info_ptrp = info_ptr;
  706. }
  707. // decodeBounds takes care of setting outCodec
  708. if (outCodec) {
  709. SkASSERT(*outCodec);
  710. }
  711. return SkCodec::kSuccess;
  712. }
  713. void AutoCleanPng::infoCallback(size_t idatLength) {
  714. png_uint_32 origWidth, origHeight;
  715. int bitDepth, encodedColorType;
  716. png_get_IHDR(fPng_ptr, fInfo_ptr, &origWidth, &origHeight, &bitDepth,
  717. &encodedColorType, nullptr, nullptr, nullptr);
  718. // TODO: Should we support 16-bits of precision for gray images?
  719. if (bitDepth == 16 && (PNG_COLOR_TYPE_GRAY == encodedColorType ||
  720. PNG_COLOR_TYPE_GRAY_ALPHA == encodedColorType)) {
  721. bitDepth = 8;
  722. png_set_strip_16(fPng_ptr);
  723. }
  724. // Now determine the default colorType and alphaType and set the required transforms.
  725. // Often, we depend on SkSwizzler to perform any transforms that we need. However, we
  726. // still depend on libpng for many of the rare and PNG-specific cases.
  727. SkEncodedInfo::Color color;
  728. SkEncodedInfo::Alpha alpha;
  729. switch (encodedColorType) {
  730. case PNG_COLOR_TYPE_PALETTE:
  731. // Extract multiple pixels with bit depths of 1, 2, and 4 from a single
  732. // byte into separate bytes (useful for paletted and grayscale images).
  733. if (bitDepth < 8) {
  734. // TODO: Should we use SkSwizzler here?
  735. bitDepth = 8;
  736. png_set_packing(fPng_ptr);
  737. }
  738. color = SkEncodedInfo::kPalette_Color;
  739. // Set the alpha depending on if a transparency chunk exists.
  740. alpha = png_get_valid(fPng_ptr, fInfo_ptr, PNG_INFO_tRNS) ?
  741. SkEncodedInfo::kUnpremul_Alpha : SkEncodedInfo::kOpaque_Alpha;
  742. break;
  743. case PNG_COLOR_TYPE_RGB:
  744. if (png_get_valid(fPng_ptr, fInfo_ptr, PNG_INFO_tRNS)) {
  745. // Convert to RGBA if transparency chunk exists.
  746. png_set_tRNS_to_alpha(fPng_ptr);
  747. color = SkEncodedInfo::kRGBA_Color;
  748. alpha = SkEncodedInfo::kBinary_Alpha;
  749. } else {
  750. color = SkEncodedInfo::kRGB_Color;
  751. alpha = SkEncodedInfo::kOpaque_Alpha;
  752. }
  753. break;
  754. case PNG_COLOR_TYPE_GRAY:
  755. // Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel.
  756. if (bitDepth < 8) {
  757. // TODO: Should we use SkSwizzler here?
  758. bitDepth = 8;
  759. png_set_expand_gray_1_2_4_to_8(fPng_ptr);
  760. }
  761. if (png_get_valid(fPng_ptr, fInfo_ptr, PNG_INFO_tRNS)) {
  762. png_set_tRNS_to_alpha(fPng_ptr);
  763. color = SkEncodedInfo::kGrayAlpha_Color;
  764. alpha = SkEncodedInfo::kBinary_Alpha;
  765. } else {
  766. color = SkEncodedInfo::kGray_Color;
  767. alpha = SkEncodedInfo::kOpaque_Alpha;
  768. }
  769. break;
  770. case PNG_COLOR_TYPE_GRAY_ALPHA:
  771. color = SkEncodedInfo::kGrayAlpha_Color;
  772. alpha = SkEncodedInfo::kUnpremul_Alpha;
  773. break;
  774. case PNG_COLOR_TYPE_RGBA:
  775. color = SkEncodedInfo::kRGBA_Color;
  776. alpha = SkEncodedInfo::kUnpremul_Alpha;
  777. break;
  778. default:
  779. // All the color types have been covered above.
  780. SkASSERT(false);
  781. color = SkEncodedInfo::kRGBA_Color;
  782. alpha = SkEncodedInfo::kUnpremul_Alpha;
  783. }
  784. const int numberPasses = png_set_interlace_handling(fPng_ptr);
  785. if (fOutCodec) {
  786. SkASSERT(nullptr == *fOutCodec);
  787. auto profile = read_color_profile(fPng_ptr, fInfo_ptr);
  788. if (profile) {
  789. switch (profile->profile()->data_color_space) {
  790. case skcms_Signature_CMYK:
  791. profile = nullptr;
  792. break;
  793. case skcms_Signature_Gray:
  794. if (SkEncodedInfo::kGray_Color != color &&
  795. SkEncodedInfo::kGrayAlpha_Color != color)
  796. {
  797. profile = nullptr;
  798. }
  799. break;
  800. default:
  801. break;
  802. }
  803. }
  804. if (encodedColorType == PNG_COLOR_TYPE_GRAY_ALPHA) {
  805. png_color_8p sigBits;
  806. if (png_get_sBIT(fPng_ptr, fInfo_ptr, &sigBits)) {
  807. if (8 == sigBits->alpha && kGraySigBit_GrayAlphaIsJustAlpha == sigBits->gray) {
  808. color = SkEncodedInfo::kXAlpha_Color;
  809. }
  810. }
  811. } else if (SkEncodedInfo::kOpaque_Alpha == alpha) {
  812. png_color_8p sigBits;
  813. if (png_get_sBIT(fPng_ptr, fInfo_ptr, &sigBits)) {
  814. if (5 == sigBits->red && 6 == sigBits->green && 5 == sigBits->blue) {
  815. // Recommend a decode to 565 if the sBIT indicates 565.
  816. color = SkEncodedInfo::k565_Color;
  817. }
  818. }
  819. }
  820. SkEncodedInfo encodedInfo = SkEncodedInfo::Make(origWidth, origHeight, color, alpha,
  821. bitDepth, std::move(profile));
  822. if (1 == numberPasses) {
  823. *fOutCodec = new SkPngNormalDecoder(std::move(encodedInfo),
  824. std::unique_ptr<SkStream>(fStream), fChunkReader, fPng_ptr, fInfo_ptr, bitDepth);
  825. } else {
  826. *fOutCodec = new SkPngInterlacedDecoder(std::move(encodedInfo),
  827. std::unique_ptr<SkStream>(fStream), fChunkReader, fPng_ptr, fInfo_ptr, bitDepth,
  828. numberPasses);
  829. }
  830. static_cast<SkPngCodec*>(*fOutCodec)->setIdatLength(idatLength);
  831. }
  832. // Release the pointers, which are now owned by the codec or the caller is expected to
  833. // take ownership.
  834. this->releasePngPtrs();
  835. }
  836. SkPngCodec::SkPngCodec(SkEncodedInfo&& encodedInfo, std::unique_ptr<SkStream> stream,
  837. SkPngChunkReader* chunkReader, void* png_ptr, void* info_ptr, int bitDepth)
  838. : INHERITED(std::move(encodedInfo), png_select_xform_format(encodedInfo), std::move(stream))
  839. , fPngChunkReader(SkSafeRef(chunkReader))
  840. , fPng_ptr(png_ptr)
  841. , fInfo_ptr(info_ptr)
  842. , fColorXformSrcRow(nullptr)
  843. , fBitDepth(bitDepth)
  844. , fIdatLength(0)
  845. , fDecodedIdat(false)
  846. {}
  847. SkPngCodec::~SkPngCodec() {
  848. this->destroyReadStruct();
  849. }
  850. void SkPngCodec::destroyReadStruct() {
  851. if (fPng_ptr) {
  852. // We will never have a nullptr fInfo_ptr with a non-nullptr fPng_ptr
  853. SkASSERT(fInfo_ptr);
  854. png_destroy_read_struct((png_struct**)&fPng_ptr, (png_info**)&fInfo_ptr, nullptr);
  855. fPng_ptr = nullptr;
  856. fInfo_ptr = nullptr;
  857. }
  858. }
  859. ///////////////////////////////////////////////////////////////////////////////
  860. // Getting the pixels
  861. ///////////////////////////////////////////////////////////////////////////////
  862. SkCodec::Result SkPngCodec::initializeXforms(const SkImageInfo& dstInfo, const Options& options) {
  863. if (setjmp(PNG_JMPBUF((png_struct*)fPng_ptr))) {
  864. SkCodecPrintf("Failed on png_read_update_info.\n");
  865. return kInvalidInput;
  866. }
  867. png_read_update_info(fPng_ptr, fInfo_ptr);
  868. // Reset fSwizzler and this->colorXform(). We can't do this in onRewind() because the
  869. // interlaced scanline decoder may need to rewind.
  870. fSwizzler.reset(nullptr);
  871. // If skcms directly supports the encoded PNG format, we should skip format
  872. // conversion in the swizzler (or skip swizzling altogether).
  873. bool skipFormatConversion = false;
  874. switch (this->getEncodedInfo().color()) {
  875. case SkEncodedInfo::kRGB_Color:
  876. if (this->getEncodedInfo().bitsPerComponent() != 16) {
  877. break;
  878. }
  879. // Fall through
  880. case SkEncodedInfo::kRGBA_Color:
  881. case SkEncodedInfo::kGray_Color:
  882. skipFormatConversion = this->colorXform();
  883. break;
  884. default:
  885. break;
  886. }
  887. if (skipFormatConversion && !options.fSubset) {
  888. fXformMode = kColorOnly_XformMode;
  889. return kSuccess;
  890. }
  891. if (SkEncodedInfo::kPalette_Color == this->getEncodedInfo().color()) {
  892. if (!this->createColorTable(dstInfo)) {
  893. return kInvalidInput;
  894. }
  895. }
  896. this->initializeSwizzler(dstInfo, options, skipFormatConversion);
  897. return kSuccess;
  898. }
  899. void SkPngCodec::initializeXformParams() {
  900. switch (fXformMode) {
  901. case kColorOnly_XformMode:
  902. fXformWidth = this->dstInfo().width();
  903. break;
  904. case kSwizzleColor_XformMode:
  905. fXformWidth = this->swizzler()->swizzleWidth();
  906. break;
  907. default:
  908. break;
  909. }
  910. }
  911. void SkPngCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& options,
  912. bool skipFormatConversion) {
  913. SkImageInfo swizzlerInfo = dstInfo;
  914. Options swizzlerOptions = options;
  915. fXformMode = kSwizzleOnly_XformMode;
  916. if (this->colorXform() && this->xformOnDecode()) {
  917. if (SkEncodedInfo::kGray_Color == this->getEncodedInfo().color()) {
  918. swizzlerInfo = swizzlerInfo.makeColorType(kGray_8_SkColorType);
  919. } else {
  920. swizzlerInfo = swizzlerInfo.makeColorType(kXformSrcColorType);
  921. }
  922. if (kPremul_SkAlphaType == dstInfo.alphaType()) {
  923. swizzlerInfo = swizzlerInfo.makeAlphaType(kUnpremul_SkAlphaType);
  924. }
  925. fXformMode = kSwizzleColor_XformMode;
  926. // Here, we swizzle into temporary memory, which is not zero initialized.
  927. // FIXME (msarett):
  928. // Is this a problem?
  929. swizzlerOptions.fZeroInitialized = kNo_ZeroInitialized;
  930. }
  931. if (skipFormatConversion) {
  932. // We cannot skip format conversion when there is a color table.
  933. SkASSERT(!fColorTable);
  934. int srcBPP = 0;
  935. switch (this->getEncodedInfo().color()) {
  936. case SkEncodedInfo::kRGB_Color:
  937. SkASSERT(this->getEncodedInfo().bitsPerComponent() == 16);
  938. srcBPP = 6;
  939. break;
  940. case SkEncodedInfo::kRGBA_Color:
  941. srcBPP = this->getEncodedInfo().bitsPerComponent() / 2;
  942. break;
  943. case SkEncodedInfo::kGray_Color:
  944. srcBPP = 1;
  945. break;
  946. default:
  947. SkASSERT(false);
  948. break;
  949. }
  950. fSwizzler = SkSwizzler::MakeSimple(srcBPP, swizzlerInfo, swizzlerOptions);
  951. } else {
  952. const SkPMColor* colors = get_color_ptr(fColorTable.get());
  953. fSwizzler = SkSwizzler::Make(this->getEncodedInfo(), colors, swizzlerInfo,
  954. swizzlerOptions);
  955. }
  956. SkASSERT(fSwizzler);
  957. }
  958. SkSampler* SkPngCodec::getSampler(bool createIfNecessary) {
  959. if (fSwizzler || !createIfNecessary) {
  960. return fSwizzler.get();
  961. }
  962. this->initializeSwizzler(this->dstInfo(), this->options(), true);
  963. return fSwizzler.get();
  964. }
  965. bool SkPngCodec::onRewind() {
  966. // This sets fPng_ptr and fInfo_ptr to nullptr. If read_header
  967. // succeeds, they will be repopulated, and if it fails, they will
  968. // remain nullptr. Any future accesses to fPng_ptr and fInfo_ptr will
  969. // come through this function which will rewind and again attempt
  970. // to reinitialize them.
  971. this->destroyReadStruct();
  972. png_structp png_ptr;
  973. png_infop info_ptr;
  974. if (kSuccess != read_header(this->stream(), fPngChunkReader.get(), nullptr,
  975. &png_ptr, &info_ptr)) {
  976. return false;
  977. }
  978. fPng_ptr = png_ptr;
  979. fInfo_ptr = info_ptr;
  980. fDecodedIdat = false;
  981. return true;
  982. }
  983. SkCodec::Result SkPngCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst,
  984. size_t rowBytes, const Options& options,
  985. int* rowsDecoded) {
  986. Result result = this->initializeXforms(dstInfo, options);
  987. if (kSuccess != result) {
  988. return result;
  989. }
  990. if (options.fSubset) {
  991. return kUnimplemented;
  992. }
  993. this->allocateStorage(dstInfo);
  994. this->initializeXformParams();
  995. return this->decodeAllRows(dst, rowBytes, rowsDecoded);
  996. }
  997. SkCodec::Result SkPngCodec::onStartIncrementalDecode(const SkImageInfo& dstInfo,
  998. void* dst, size_t rowBytes, const SkCodec::Options& options) {
  999. Result result = this->initializeXforms(dstInfo, options);
  1000. if (kSuccess != result) {
  1001. return result;
  1002. }
  1003. this->allocateStorage(dstInfo);
  1004. int firstRow, lastRow;
  1005. if (options.fSubset) {
  1006. firstRow = options.fSubset->top();
  1007. lastRow = options.fSubset->bottom() - 1;
  1008. } else {
  1009. firstRow = 0;
  1010. lastRow = dstInfo.height() - 1;
  1011. }
  1012. this->setRange(firstRow, lastRow, dst, rowBytes);
  1013. return kSuccess;
  1014. }
  1015. SkCodec::Result SkPngCodec::onIncrementalDecode(int* rowsDecoded) {
  1016. // FIXME: Only necessary on the first call.
  1017. this->initializeXformParams();
  1018. return this->decode(rowsDecoded);
  1019. }
  1020. std::unique_ptr<SkCodec> SkPngCodec::MakeFromStream(std::unique_ptr<SkStream> stream,
  1021. Result* result, SkPngChunkReader* chunkReader) {
  1022. SkCodec* outCodec = nullptr;
  1023. *result = read_header(stream.get(), chunkReader, &outCodec, nullptr, nullptr);
  1024. if (kSuccess == *result) {
  1025. // Codec has taken ownership of the stream.
  1026. SkASSERT(outCodec);
  1027. stream.release();
  1028. }
  1029. return std::unique_ptr<SkCodec>(outCodec);
  1030. }