SkCodec.h 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921
  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. #ifndef SkCodec_DEFINED
  8. #define SkCodec_DEFINED
  9. #include "../private/SkNoncopyable.h"
  10. #include "../private/SkTemplates.h"
  11. #include "../private/SkEncodedInfo.h"
  12. #include "SkCodecAnimation.h"
  13. #include "SkColor.h"
  14. #include "SkEncodedImageFormat.h"
  15. #include "SkEncodedOrigin.h"
  16. #include "SkImageInfo.h"
  17. #include "SkPixmap.h"
  18. #include "SkSize.h"
  19. #include "SkStream.h"
  20. #include "SkTypes.h"
  21. #include "SkYUVASizeInfo.h"
  22. #include <vector>
  23. class SkColorSpace;
  24. class SkData;
  25. class SkFrameHolder;
  26. class SkPngChunkReader;
  27. class SkSampler;
  28. namespace DM {
  29. class CodecSrc;
  30. class ColorCodecSrc;
  31. }
  32. /**
  33. * Abstraction layer directly on top of an image codec.
  34. */
  35. class SK_API SkCodec : SkNoncopyable {
  36. public:
  37. /**
  38. * Minimum number of bytes that must be buffered in SkStream input.
  39. *
  40. * An SkStream passed to NewFromStream must be able to use this many
  41. * bytes to determine the image type. Then the same SkStream must be
  42. * passed to the correct decoder to read from the beginning.
  43. *
  44. * This can be accomplished by implementing peek() to support peeking
  45. * this many bytes, or by implementing rewind() to be able to rewind()
  46. * after reading this many bytes.
  47. */
  48. static constexpr size_t MinBufferedBytesNeeded() { return 32; }
  49. /**
  50. * Error codes for various SkCodec methods.
  51. */
  52. enum Result {
  53. /**
  54. * General return value for success.
  55. */
  56. kSuccess,
  57. /**
  58. * The input is incomplete. A partial image was generated.
  59. */
  60. kIncompleteInput,
  61. /**
  62. * Like kIncompleteInput, except the input had an error.
  63. *
  64. * If returned from an incremental decode, decoding cannot continue,
  65. * even with more data.
  66. */
  67. kErrorInInput,
  68. /**
  69. * The generator cannot convert to match the request, ignoring
  70. * dimensions.
  71. */
  72. kInvalidConversion,
  73. /**
  74. * The generator cannot scale to requested size.
  75. */
  76. kInvalidScale,
  77. /**
  78. * Parameters (besides info) are invalid. e.g. NULL pixels, rowBytes
  79. * too small, etc.
  80. */
  81. kInvalidParameters,
  82. /**
  83. * The input did not contain a valid image.
  84. */
  85. kInvalidInput,
  86. /**
  87. * Fulfilling this request requires rewinding the input, which is not
  88. * supported for this input.
  89. */
  90. kCouldNotRewind,
  91. /**
  92. * An internal error, such as OOM.
  93. */
  94. kInternalError,
  95. /**
  96. * This method is not implemented by this codec.
  97. * FIXME: Perhaps this should be kUnsupported?
  98. */
  99. kUnimplemented,
  100. };
  101. /**
  102. * Readable string representing the error code.
  103. */
  104. static const char* ResultToString(Result);
  105. /**
  106. * If this stream represents an encoded image that we know how to decode,
  107. * return an SkCodec that can decode it. Otherwise return NULL.
  108. *
  109. * As stated above, this call must be able to peek or read
  110. * MinBufferedBytesNeeded to determine the correct format, and then start
  111. * reading from the beginning. First it will attempt to peek, and it
  112. * assumes that if less than MinBufferedBytesNeeded bytes (but more than
  113. * zero) are returned, this is because the stream is shorter than this,
  114. * so falling back to reading would not provide more data. If peek()
  115. * returns zero bytes, this call will instead attempt to read(). This
  116. * will require that the stream can be rewind()ed.
  117. *
  118. * If Result is not NULL, it will be set to either kSuccess if an SkCodec
  119. * is returned or a reason for the failure if NULL is returned.
  120. *
  121. * If SkPngChunkReader is not NULL, take a ref and pass it to libpng if
  122. * the image is a png.
  123. *
  124. * If the SkPngChunkReader is not NULL then:
  125. * If the image is not a PNG, the SkPngChunkReader will be ignored.
  126. * If the image is a PNG, the SkPngChunkReader will be reffed.
  127. * If the PNG has unknown chunks, the SkPngChunkReader will be used
  128. * to handle these chunks. SkPngChunkReader will be called to read
  129. * any unknown chunk at any point during the creation of the codec
  130. * or the decode. Note that if SkPngChunkReader fails to read a
  131. * chunk, this could result in a failure to create the codec or a
  132. * failure to decode the image.
  133. * If the PNG does not contain unknown chunks, the SkPngChunkReader
  134. * will not be used or modified.
  135. *
  136. * If NULL is returned, the stream is deleted immediately. Otherwise, the
  137. * SkCodec takes ownership of it, and will delete it when done with it.
  138. */
  139. static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result* = nullptr,
  140. SkPngChunkReader* = nullptr);
  141. /**
  142. * If this data represents an encoded image that we know how to decode,
  143. * return an SkCodec that can decode it. Otherwise return NULL.
  144. *
  145. * If the SkPngChunkReader is not NULL then:
  146. * If the image is not a PNG, the SkPngChunkReader will be ignored.
  147. * If the image is a PNG, the SkPngChunkReader will be reffed.
  148. * If the PNG has unknown chunks, the SkPngChunkReader will be used
  149. * to handle these chunks. SkPngChunkReader will be called to read
  150. * any unknown chunk at any point during the creation of the codec
  151. * or the decode. Note that if SkPngChunkReader fails to read a
  152. * chunk, this could result in a failure to create the codec or a
  153. * failure to decode the image.
  154. * If the PNG does not contain unknown chunks, the SkPngChunkReader
  155. * will not be used or modified.
  156. */
  157. static std::unique_ptr<SkCodec> MakeFromData(sk_sp<SkData>, SkPngChunkReader* = nullptr);
  158. virtual ~SkCodec();
  159. /**
  160. * Return a reasonable SkImageInfo to decode into.
  161. */
  162. SkImageInfo getInfo() const { return fEncodedInfo.makeImageInfo(); }
  163. SkISize dimensions() const { return {fEncodedInfo.width(), fEncodedInfo.height()}; }
  164. SkIRect bounds() const {
  165. return SkIRect::MakeWH(fEncodedInfo.width(), fEncodedInfo.height());
  166. }
  167. /**
  168. * Returns the image orientation stored in the EXIF data.
  169. * If there is no EXIF data, or if we cannot read the EXIF data, returns kTopLeft.
  170. */
  171. SkEncodedOrigin getOrigin() const { return fOrigin; }
  172. /**
  173. * Return a size that approximately supports the desired scale factor.
  174. * The codec may not be able to scale efficiently to the exact scale
  175. * factor requested, so return a size that approximates that scale.
  176. * The returned value is the codec's suggestion for the closest valid
  177. * scale that it can natively support
  178. */
  179. SkISize getScaledDimensions(float desiredScale) const {
  180. // Negative and zero scales are errors.
  181. SkASSERT(desiredScale > 0.0f);
  182. if (desiredScale <= 0.0f) {
  183. return SkISize::Make(0, 0);
  184. }
  185. // Upscaling is not supported. Return the original size if the client
  186. // requests an upscale.
  187. if (desiredScale >= 1.0f) {
  188. return this->dimensions();
  189. }
  190. return this->onGetScaledDimensions(desiredScale);
  191. }
  192. /**
  193. * Return (via desiredSubset) a subset which can decoded from this codec,
  194. * or false if this codec cannot decode subsets or anything similar to
  195. * desiredSubset.
  196. *
  197. * @param desiredSubset In/out parameter. As input, a desired subset of
  198. * the original bounds (as specified by getInfo). If true is returned,
  199. * desiredSubset may have been modified to a subset which is
  200. * supported. Although a particular change may have been made to
  201. * desiredSubset to create something supported, it is possible other
  202. * changes could result in a valid subset.
  203. * If false is returned, desiredSubset's value is undefined.
  204. * @return true if this codec supports decoding desiredSubset (as
  205. * returned, potentially modified)
  206. */
  207. bool getValidSubset(SkIRect* desiredSubset) const {
  208. return this->onGetValidSubset(desiredSubset);
  209. }
  210. /**
  211. * Format of the encoded data.
  212. */
  213. SkEncodedImageFormat getEncodedFormat() const { return this->onGetEncodedFormat(); }
  214. /**
  215. * Whether or not the memory passed to getPixels is zero initialized.
  216. */
  217. enum ZeroInitialized {
  218. /**
  219. * The memory passed to getPixels is zero initialized. The SkCodec
  220. * may take advantage of this by skipping writing zeroes.
  221. */
  222. kYes_ZeroInitialized,
  223. /**
  224. * The memory passed to getPixels has not been initialized to zero,
  225. * so the SkCodec must write all zeroes to memory.
  226. *
  227. * This is the default. It will be used if no Options struct is used.
  228. */
  229. kNo_ZeroInitialized,
  230. };
  231. /**
  232. * Additional options to pass to getPixels.
  233. */
  234. struct Options {
  235. Options()
  236. : fZeroInitialized(kNo_ZeroInitialized)
  237. , fSubset(nullptr)
  238. , fFrameIndex(0)
  239. , fPriorFrame(kNoFrame)
  240. {}
  241. ZeroInitialized fZeroInitialized;
  242. /**
  243. * If not NULL, represents a subset of the original image to decode.
  244. * Must be within the bounds returned by getInfo().
  245. * If the EncodedFormat is SkEncodedImageFormat::kWEBP (the only one which
  246. * currently supports subsets), the top and left values must be even.
  247. *
  248. * In getPixels and incremental decode, we will attempt to decode the
  249. * exact rectangular subset specified by fSubset.
  250. *
  251. * In a scanline decode, it does not make sense to specify a subset
  252. * top or subset height, since the client already controls which rows
  253. * to get and which rows to skip. During scanline decodes, we will
  254. * require that the subset top be zero and the subset height be equal
  255. * to the full height. We will, however, use the values of
  256. * subset left and subset width to decode partial scanlines on calls
  257. * to getScanlines().
  258. */
  259. const SkIRect* fSubset;
  260. /**
  261. * The frame to decode.
  262. *
  263. * Only meaningful for multi-frame images.
  264. */
  265. int fFrameIndex;
  266. /**
  267. * If not kNoFrame, the dst already contains the prior frame at this index.
  268. *
  269. * Only meaningful for multi-frame images.
  270. *
  271. * If fFrameIndex needs to be blended with a prior frame (as reported by
  272. * getFrameInfo[fFrameIndex].fRequiredFrame), the client can set this to
  273. * any non-kRestorePrevious frame in [fRequiredFrame, fFrameIndex) to
  274. * indicate that that frame is already in the dst. Options.fZeroInitialized
  275. * is ignored in this case.
  276. *
  277. * If set to kNoFrame, the codec will decode any necessary required frame(s) first.
  278. */
  279. int fPriorFrame;
  280. };
  281. /**
  282. * Decode into the given pixels, a block of memory of size at
  283. * least (info.fHeight - 1) * rowBytes + (info.fWidth *
  284. * bytesPerPixel)
  285. *
  286. * Repeated calls to this function should give the same results,
  287. * allowing the PixelRef to be immutable.
  288. *
  289. * @param info A description of the format (config, size)
  290. * expected by the caller. This can simply be identical
  291. * to the info returned by getInfo().
  292. *
  293. * This contract also allows the caller to specify
  294. * different output-configs, which the implementation can
  295. * decide to support or not.
  296. *
  297. * A size that does not match getInfo() implies a request
  298. * to scale. If the generator cannot perform this scale,
  299. * it will return kInvalidScale.
  300. *
  301. * If the info contains a non-null SkColorSpace, the codec
  302. * will perform the appropriate color space transformation.
  303. * If the caller passes in the same color space that was
  304. * reported by the codec, the color space transformation is
  305. * a no-op.
  306. *
  307. * If a scanline decode is in progress, scanline mode will end, requiring the client to call
  308. * startScanlineDecode() in order to return to decoding scanlines.
  309. *
  310. * @return Result kSuccess, or another value explaining the type of failure.
  311. */
  312. Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options*);
  313. /**
  314. * Simplified version of getPixels() that uses the default Options.
  315. */
  316. Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) {
  317. return this->getPixels(info, pixels, rowBytes, nullptr);
  318. }
  319. Result getPixels(const SkPixmap& pm, const Options* opts = nullptr) {
  320. return this->getPixels(pm.info(), pm.writable_addr(), pm.rowBytes(), opts);
  321. }
  322. /**
  323. * If decoding to YUV is supported, this returns true. Otherwise, this
  324. * returns false and does not modify any of the parameters.
  325. *
  326. * @param sizeInfo Output parameter indicating the sizes and required
  327. * allocation widths of the Y, U, V, and A planes. Given current codec
  328. * limitations the size of the A plane will always be 0 and the Y, U, V
  329. * channels will always be planar.
  330. * @param colorSpace Output parameter. If non-NULL this is set to kJPEG,
  331. * otherwise this is ignored.
  332. */
  333. bool queryYUV8(SkYUVASizeInfo* sizeInfo, SkYUVColorSpace* colorSpace) const {
  334. if (nullptr == sizeInfo) {
  335. return false;
  336. }
  337. bool result = this->onQueryYUV8(sizeInfo, colorSpace);
  338. if (result) {
  339. for (int i = 0; i <= 2; ++i) {
  340. SkASSERT(sizeInfo->fSizes[i].fWidth > 0 && sizeInfo->fSizes[i].fHeight > 0 &&
  341. sizeInfo->fWidthBytes[i] > 0);
  342. }
  343. SkASSERT(!sizeInfo->fSizes[3].fWidth &&
  344. !sizeInfo->fSizes[3].fHeight &&
  345. !sizeInfo->fWidthBytes[3]);
  346. }
  347. return result;
  348. }
  349. /**
  350. * Returns kSuccess, or another value explaining the type of failure.
  351. * This always attempts to perform a full decode. If the client only
  352. * wants size, it should call queryYUV8().
  353. *
  354. * @param sizeInfo Needs to exactly match the values returned by the
  355. * query, except the WidthBytes may be larger than the
  356. * recommendation (but not smaller).
  357. * @param planes Memory for each of the Y, U, and V planes.
  358. */
  359. Result getYUV8Planes(const SkYUVASizeInfo& sizeInfo, void* planes[SkYUVASizeInfo::kMaxCount]) {
  360. if (!planes || !planes[0] || !planes[1] || !planes[2]) {
  361. return kInvalidInput;
  362. }
  363. SkASSERT(!planes[3]); // TODO: is this a fair assumption?
  364. if (!this->rewindIfNeeded()) {
  365. return kCouldNotRewind;
  366. }
  367. return this->onGetYUV8Planes(sizeInfo, planes);
  368. }
  369. /**
  370. * Prepare for an incremental decode with the specified options.
  371. *
  372. * This may require a rewind.
  373. *
  374. * @param dstInfo Info of the destination. If the dimensions do not match
  375. * those of getInfo, this implies a scale.
  376. * @param dst Memory to write to. Needs to be large enough to hold the subset,
  377. * if present, or the full image as described in dstInfo.
  378. * @param options Contains decoding options, including if memory is zero
  379. * initialized and whether to decode a subset.
  380. * @return Enum representing success or reason for failure.
  381. */
  382. Result startIncrementalDecode(const SkImageInfo& dstInfo, void* dst, size_t rowBytes,
  383. const Options*);
  384. Result startIncrementalDecode(const SkImageInfo& dstInfo, void* dst, size_t rowBytes) {
  385. return this->startIncrementalDecode(dstInfo, dst, rowBytes, nullptr);
  386. }
  387. /**
  388. * Start/continue the incremental decode.
  389. *
  390. * Not valid to call before calling startIncrementalDecode().
  391. *
  392. * After the first call, should only be called again if more data has been
  393. * provided to the source SkStream.
  394. *
  395. * Unlike getPixels and getScanlines, this does not do any filling. This is
  396. * left up to the caller, since they may be skipping lines or continuing the
  397. * decode later. In the latter case, they may choose to initialize all lines
  398. * first, or only initialize the remaining lines after the first call.
  399. *
  400. * @param rowsDecoded Optional output variable returning the total number of
  401. * lines initialized. Only meaningful if this method returns kIncompleteInput.
  402. * Otherwise the implementation may not set it.
  403. * Note that some implementations may have initialized this many rows, but
  404. * not necessarily finished those rows (e.g. interlaced PNG). This may be
  405. * useful for determining what rows the client needs to initialize.
  406. * @return kSuccess if all lines requested in startIncrementalDecode have
  407. * been completely decoded. kIncompleteInput otherwise.
  408. */
  409. Result incrementalDecode(int* rowsDecoded = nullptr) {
  410. if (!fStartedIncrementalDecode) {
  411. return kInvalidParameters;
  412. }
  413. return this->onIncrementalDecode(rowsDecoded);
  414. }
  415. /**
  416. * The remaining functions revolve around decoding scanlines.
  417. */
  418. /**
  419. * Prepare for a scanline decode with the specified options.
  420. *
  421. * After this call, this class will be ready to decode the first scanline.
  422. *
  423. * This must be called in order to call getScanlines or skipScanlines.
  424. *
  425. * This may require rewinding the stream.
  426. *
  427. * Not all SkCodecs support this.
  428. *
  429. * @param dstInfo Info of the destination. If the dimensions do not match
  430. * those of getInfo, this implies a scale.
  431. * @param options Contains decoding options, including if memory is zero
  432. * initialized.
  433. * @return Enum representing success or reason for failure.
  434. */
  435. Result startScanlineDecode(const SkImageInfo& dstInfo, const Options* options);
  436. /**
  437. * Simplified version of startScanlineDecode() that uses the default Options.
  438. */
  439. Result startScanlineDecode(const SkImageInfo& dstInfo) {
  440. return this->startScanlineDecode(dstInfo, nullptr);
  441. }
  442. /**
  443. * Write the next countLines scanlines into dst.
  444. *
  445. * Not valid to call before calling startScanlineDecode().
  446. *
  447. * @param dst Must be non-null, and large enough to hold countLines
  448. * scanlines of size rowBytes.
  449. * @param countLines Number of lines to write.
  450. * @param rowBytes Number of bytes per row. Must be large enough to hold
  451. * a scanline based on the SkImageInfo used to create this object.
  452. * @return the number of lines successfully decoded. If this value is
  453. * less than countLines, this will fill the remaining lines with a
  454. * default value.
  455. */
  456. int getScanlines(void* dst, int countLines, size_t rowBytes);
  457. /**
  458. * Skip count scanlines.
  459. *
  460. * Not valid to call before calling startScanlineDecode().
  461. *
  462. * The default version just calls onGetScanlines and discards the dst.
  463. * NOTE: If skipped lines are the only lines with alpha, this default
  464. * will make reallyHasAlpha return true, when it could have returned
  465. * false.
  466. *
  467. * @return true if the scanlines were successfully skipped
  468. * false on failure, possible reasons for failure include:
  469. * An incomplete input image stream.
  470. * Calling this function before calling startScanlineDecode().
  471. * If countLines is less than zero or so large that it moves
  472. * the current scanline past the end of the image.
  473. */
  474. bool skipScanlines(int countLines);
  475. /**
  476. * The order in which rows are output from the scanline decoder is not the
  477. * same for all variations of all image types. This explains the possible
  478. * output row orderings.
  479. */
  480. enum SkScanlineOrder {
  481. /*
  482. * By far the most common, this indicates that the image can be decoded
  483. * reliably using the scanline decoder, and that rows will be output in
  484. * the logical order.
  485. */
  486. kTopDown_SkScanlineOrder,
  487. /*
  488. * This indicates that the scanline decoder reliably outputs rows, but
  489. * they will be returned in reverse order. If the scanline format is
  490. * kBottomUp, the nextScanline() API can be used to determine the actual
  491. * y-coordinate of the next output row, but the client is not forced
  492. * to take advantage of this, given that it's not too tough to keep
  493. * track independently.
  494. *
  495. * For full image decodes, it is safe to get all of the scanlines at
  496. * once, since the decoder will handle inverting the rows as it
  497. * decodes.
  498. *
  499. * For subset decodes and sampling, it is simplest to get and skip
  500. * scanlines one at a time, using the nextScanline() API. It is
  501. * possible to ask for larger chunks at a time, but this should be used
  502. * with caution. As with full image decodes, the decoder will handle
  503. * inverting the requested rows, but rows will still be delivered
  504. * starting from the bottom of the image.
  505. *
  506. * Upside down bmps are an example.
  507. */
  508. kBottomUp_SkScanlineOrder,
  509. };
  510. /**
  511. * An enum representing the order in which scanlines will be returned by
  512. * the scanline decoder.
  513. *
  514. * This is undefined before startScanlineDecode() is called.
  515. */
  516. SkScanlineOrder getScanlineOrder() const { return this->onGetScanlineOrder(); }
  517. /**
  518. * Returns the y-coordinate of the next row to be returned by the scanline
  519. * decoder.
  520. *
  521. * This will equal fCurrScanline, except in the case of strangely
  522. * encoded image types (bottom-up bmps).
  523. *
  524. * Results are undefined when not in scanline decoding mode.
  525. */
  526. int nextScanline() const { return this->outputScanline(fCurrScanline); }
  527. /**
  528. * Returns the output y-coordinate of the row that corresponds to an input
  529. * y-coordinate. The input y-coordinate represents where the scanline
  530. * is located in the encoded data.
  531. *
  532. * This will equal inputScanline, except in the case of strangely
  533. * encoded image types (bottom-up bmps, interlaced gifs).
  534. */
  535. int outputScanline(int inputScanline) const;
  536. /**
  537. * Return the number of frames in the image.
  538. *
  539. * May require reading through the stream.
  540. */
  541. int getFrameCount() {
  542. return this->onGetFrameCount();
  543. }
  544. // Sentinel value used when a frame index implies "no frame":
  545. // - FrameInfo::fRequiredFrame set to this value means the frame
  546. // is independent.
  547. // - Options::fPriorFrame set to this value means no (relevant) prior frame
  548. // is residing in dst's memory.
  549. static constexpr int kNoFrame = -1;
  550. // This transitional definition was added in August 2018, and will eventually be removed.
  551. #ifdef SK_LEGACY_SKCODEC_NONE_ENUM
  552. static constexpr int kNone = kNoFrame;
  553. #endif
  554. /**
  555. * Information about individual frames in a multi-framed image.
  556. */
  557. struct FrameInfo {
  558. /**
  559. * The frame that this frame needs to be blended with, or
  560. * kNoFrame if this frame is independent.
  561. *
  562. * Note that this is the *earliest* frame that can be used
  563. * for blending. Any frame from [fRequiredFrame, i) can be
  564. * used, unless its fDisposalMethod is kRestorePrevious.
  565. */
  566. int fRequiredFrame;
  567. /**
  568. * Number of milliseconds to show this frame.
  569. */
  570. int fDuration;
  571. /**
  572. * Whether the end marker for this frame is contained in the stream.
  573. *
  574. * Note: this does not guarantee that an attempt to decode will be complete.
  575. * There could be an error in the stream.
  576. */
  577. bool fFullyReceived;
  578. /**
  579. * This is conservative; it will still return non-opaque if e.g. a
  580. * color index-based frame has a color with alpha but does not use it.
  581. */
  582. SkAlphaType fAlphaType;
  583. /**
  584. * How this frame should be modified before decoding the next one.
  585. */
  586. SkCodecAnimation::DisposalMethod fDisposalMethod;
  587. };
  588. /**
  589. * Return info about a single frame.
  590. *
  591. * Only supported by multi-frame images. Does not read through the stream,
  592. * so it should be called after getFrameCount() to parse any frames that
  593. * have not already been parsed.
  594. */
  595. bool getFrameInfo(int index, FrameInfo* info) const {
  596. if (index < 0) {
  597. return false;
  598. }
  599. return this->onGetFrameInfo(index, info);
  600. }
  601. /**
  602. * Return info about all the frames in the image.
  603. *
  604. * May require reading through the stream to determine info about the
  605. * frames (including the count).
  606. *
  607. * As such, future decoding calls may require a rewind.
  608. *
  609. * For still (non-animated) image codecs, this will return an empty vector.
  610. */
  611. std::vector<FrameInfo> getFrameInfo();
  612. static constexpr int kRepetitionCountInfinite = -1;
  613. /**
  614. * Return the number of times to repeat, if this image is animated. This number does not
  615. * include the first play through of each frame. For example, a repetition count of 4 means
  616. * that each frame is played 5 times and then the animation stops.
  617. *
  618. * It can return kRepetitionCountInfinite, a negative number, meaning that the animation
  619. * should loop forever.
  620. *
  621. * May require reading the stream to find the repetition count.
  622. *
  623. * As such, future decoding calls may require a rewind.
  624. *
  625. * For still (non-animated) image codecs, this will return 0.
  626. */
  627. int getRepetitionCount() {
  628. return this->onGetRepetitionCount();
  629. }
  630. protected:
  631. const SkEncodedInfo& getEncodedInfo() const { return fEncodedInfo; }
  632. using XformFormat = skcms_PixelFormat;
  633. SkCodec(SkEncodedInfo&&,
  634. XformFormat srcFormat,
  635. std::unique_ptr<SkStream>,
  636. SkEncodedOrigin = kTopLeft_SkEncodedOrigin);
  637. virtual SkISize onGetScaledDimensions(float /*desiredScale*/) const {
  638. // By default, scaling is not supported.
  639. return this->dimensions();
  640. }
  641. // FIXME: What to do about subsets??
  642. /**
  643. * Subclasses should override if they support dimensions other than the
  644. * srcInfo's.
  645. */
  646. virtual bool onDimensionsSupported(const SkISize&) {
  647. return false;
  648. }
  649. virtual SkEncodedImageFormat onGetEncodedFormat() const = 0;
  650. /**
  651. * @param rowsDecoded When the encoded image stream is incomplete, this function
  652. * will return kIncompleteInput and rowsDecoded will be set to
  653. * the number of scanlines that were successfully decoded.
  654. * This will allow getPixels() to fill the uninitialized memory.
  655. */
  656. virtual Result onGetPixels(const SkImageInfo& info,
  657. void* pixels, size_t rowBytes, const Options&,
  658. int* rowsDecoded) = 0;
  659. virtual bool onQueryYUV8(SkYUVASizeInfo*, SkYUVColorSpace*) const {
  660. return false;
  661. }
  662. virtual Result onGetYUV8Planes(const SkYUVASizeInfo&,
  663. void*[SkYUVASizeInfo::kMaxCount] /*planes*/) {
  664. return kUnimplemented;
  665. }
  666. virtual bool onGetValidSubset(SkIRect* /*desiredSubset*/) const {
  667. // By default, subsets are not supported.
  668. return false;
  669. }
  670. /**
  671. * If the stream was previously read, attempt to rewind.
  672. *
  673. * If the stream needed to be rewound, call onRewind.
  674. * @returns true if the codec is at the right position and can be used.
  675. * false if there was a failure to rewind.
  676. *
  677. * This is called by getPixels(), getYUV8Planes(), startIncrementalDecode() and
  678. * startScanlineDecode(). Subclasses may call if they need to rewind at another time.
  679. */
  680. bool SK_WARN_UNUSED_RESULT rewindIfNeeded();
  681. /**
  682. * Called by rewindIfNeeded, if the stream needed to be rewound.
  683. *
  684. * Subclasses should do any set up needed after a rewind.
  685. */
  686. virtual bool onRewind() {
  687. return true;
  688. }
  689. /**
  690. * Get method for the input stream
  691. */
  692. SkStream* stream() {
  693. return fStream.get();
  694. }
  695. /**
  696. * The remaining functions revolve around decoding scanlines.
  697. */
  698. /**
  699. * Most images types will be kTopDown and will not need to override this function.
  700. */
  701. virtual SkScanlineOrder onGetScanlineOrder() const { return kTopDown_SkScanlineOrder; }
  702. const SkImageInfo& dstInfo() const { return fDstInfo; }
  703. const Options& options() const { return fOptions; }
  704. /**
  705. * Returns the number of scanlines that have been decoded so far.
  706. * This is unaffected by the SkScanlineOrder.
  707. *
  708. * Returns -1 if we have not started a scanline decode.
  709. */
  710. int currScanline() const { return fCurrScanline; }
  711. virtual int onOutputScanline(int inputScanline) const;
  712. /**
  713. * Return whether we can convert to dst.
  714. *
  715. * Will be called for the appropriate frame, prior to initializing the colorXform.
  716. */
  717. virtual bool conversionSupported(const SkImageInfo& dst, bool srcIsOpaque,
  718. bool needsColorXform);
  719. // Some classes never need a colorXform e.g.
  720. // - ICO uses its embedded codec's colorXform
  721. // - WBMP is just Black/White
  722. virtual bool usesColorXform() const { return true; }
  723. void applyColorXform(void* dst, const void* src, int count) const;
  724. bool colorXform() const { return fXformTime != kNo_XformTime; }
  725. bool xformOnDecode() const { return fXformTime == kDecodeRow_XformTime; }
  726. virtual int onGetFrameCount() {
  727. return 1;
  728. }
  729. virtual bool onGetFrameInfo(int, FrameInfo*) const {
  730. return false;
  731. }
  732. virtual int onGetRepetitionCount() {
  733. return 0;
  734. }
  735. private:
  736. const SkEncodedInfo fEncodedInfo;
  737. const XformFormat fSrcXformFormat;
  738. std::unique_ptr<SkStream> fStream;
  739. bool fNeedsRewind;
  740. const SkEncodedOrigin fOrigin;
  741. SkImageInfo fDstInfo;
  742. Options fOptions;
  743. enum XformTime {
  744. kNo_XformTime,
  745. kPalette_XformTime,
  746. kDecodeRow_XformTime,
  747. };
  748. XformTime fXformTime;
  749. XformFormat fDstXformFormat; // Based on fDstInfo.
  750. skcms_ICCProfile fDstProfile;
  751. skcms_AlphaFormat fDstXformAlphaFormat;
  752. // Only meaningful during scanline decodes.
  753. int fCurrScanline;
  754. bool fStartedIncrementalDecode;
  755. bool initializeColorXform(const SkImageInfo& dstInfo, SkEncodedInfo::Alpha, bool srcIsOpaque);
  756. /**
  757. * Return whether these dimensions are supported as a scale.
  758. *
  759. * The codec may choose to cache the information about scale and subset.
  760. * Either way, the same information will be passed to onGetPixels/onStart
  761. * on success.
  762. *
  763. * This must return true for a size returned from getScaledDimensions.
  764. */
  765. bool dimensionsSupported(const SkISize& dim) {
  766. return dim == this->dimensions() || this->onDimensionsSupported(dim);
  767. }
  768. /**
  769. * For multi-framed images, return the object with information about the frames.
  770. */
  771. virtual const SkFrameHolder* getFrameHolder() const {
  772. return nullptr;
  773. }
  774. /**
  775. * Check for a valid Options.fFrameIndex, and decode prior frames if necessary.
  776. */
  777. Result handleFrameIndex(const SkImageInfo&, void* pixels, size_t rowBytes, const Options&);
  778. // Methods for scanline decoding.
  779. virtual Result onStartScanlineDecode(const SkImageInfo& /*dstInfo*/,
  780. const Options& /*options*/) {
  781. return kUnimplemented;
  782. }
  783. virtual Result onStartIncrementalDecode(const SkImageInfo& /*dstInfo*/, void*, size_t,
  784. const Options&) {
  785. return kUnimplemented;
  786. }
  787. virtual Result onIncrementalDecode(int*) {
  788. return kUnimplemented;
  789. }
  790. virtual bool onSkipScanlines(int /*countLines*/) { return false; }
  791. virtual int onGetScanlines(void* /*dst*/, int /*countLines*/, size_t /*rowBytes*/) { return 0; }
  792. /**
  793. * On an incomplete decode, getPixels() and getScanlines() will call this function
  794. * to fill any uinitialized memory.
  795. *
  796. * @param dstInfo Contains the destination color type
  797. * Contains the destination alpha type
  798. * Contains the destination width
  799. * The height stored in this info is unused
  800. * @param dst Pointer to the start of destination pixel memory
  801. * @param rowBytes Stride length in destination pixel memory
  802. * @param zeroInit Indicates if memory is zero initialized
  803. * @param linesRequested Number of lines that the client requested
  804. * @param linesDecoded Number of lines that were successfully decoded
  805. */
  806. void fillIncompleteImage(const SkImageInfo& dstInfo, void* dst, size_t rowBytes,
  807. ZeroInitialized zeroInit, int linesRequested, int linesDecoded);
  808. /**
  809. * Return an object which will allow forcing scanline decodes to sample in X.
  810. *
  811. * May create a sampler, if one is not currently being used. Otherwise, does
  812. * not affect ownership.
  813. *
  814. * Only valid during scanline decoding or incremental decoding.
  815. */
  816. virtual SkSampler* getSampler(bool /*createIfNecessary*/) { return nullptr; }
  817. friend class DM::CodecSrc; // for fillIncompleteImage
  818. friend class SkSampledCodec;
  819. friend class SkIcoCodec;
  820. friend class SkAndroidCodec; // for fEncodedInfo
  821. };
  822. #endif // SkCodec_DEFINED