blob: a49586ffeb1ecf6ff337b1dc12fd0fe8120be113 [file] [log] [blame]
scroggof24f2242015-03-03 08:59:20 -08001/*
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
8#include "SkCodec.h"
9#include "SkData.h"
msarett74114382015-03-16 11:55:18 -070010#include "SkCodec_libbmp.h"
msarett9bde9182015-03-25 05:27:48 -070011#include "SkCodec_libico.h"
scroggof24f2242015-03-03 08:59:20 -080012#include "SkCodec_libpng.h"
13#include "SkStream.h"
14
msarett74114382015-03-16 11:55:18 -070015struct DecoderProc {
16 bool (*IsFormat)(SkStream*);
17 SkCodec* (*NewFromStream)(SkStream*);
18};
19
20static const DecoderProc gDecoderProcs[] = {
21 { SkPngCodec::IsPng, SkPngCodec::NewFromStream },
msarett9bde9182015-03-25 05:27:48 -070022 { SkIcoCodec::IsIco, SkIcoCodec::NewFromStream },
msarett74114382015-03-16 11:55:18 -070023 { SkBmpCodec::IsBmp, SkBmpCodec::NewFromStream }
24};
25
scroggof24f2242015-03-03 08:59:20 -080026SkCodec* SkCodec::NewFromStream(SkStream* stream) {
27 if (!stream) {
28 return NULL;
29 }
msarett74114382015-03-16 11:55:18 -070030 for (uint32_t i = 0; i < SK_ARRAY_COUNT(gDecoderProcs); i++) {
31 DecoderProc proc = gDecoderProcs[i];
32 const bool correctFormat = proc.IsFormat(stream);
33 if (!stream->rewind()) {
34 return NULL;
35 }
36 if (correctFormat) {
37 return proc.NewFromStream(stream);
38 }
scroggof24f2242015-03-03 08:59:20 -080039 }
scroggof24f2242015-03-03 08:59:20 -080040 return NULL;
41}
42
43SkCodec* SkCodec::NewFromData(SkData* data) {
44 if (!data) {
45 return NULL;
46 }
47 return NewFromStream(SkNEW_ARGS(SkMemoryStream, (data)));
48}
49
50SkCodec::SkCodec(const SkImageInfo& info, SkStream* stream)
reed3ef71e32015-03-19 08:31:14 -070051 : INHERITED(info)
halcanaryb880d7f2015-03-26 06:29:03 -070052#ifdef SK_SUPPORT_LEGACY_BOOL_ONGETINFO
reed3ef71e32015-03-19 08:31:14 -070053 , fInfo(info)
halcanaryb880d7f2015-03-26 06:29:03 -070054#endif
scroggof24f2242015-03-03 08:59:20 -080055 , fStream(stream)
56 , fNeedsRewind(false)
57{}
58
59bool SkCodec::rewindIfNeeded() {
60 // Store the value of fNeedsRewind so we can update it. Next read will
61 // require a rewind.
62 const bool neededRewind = fNeedsRewind;
63 fNeedsRewind = true;
64 return !neededRewind || fStream->rewind();
65}
scroggo05245902015-03-25 11:11:52 -070066
67SkScanlineDecoder* SkCodec::getScanlineDecoder(const SkImageInfo& dstInfo) {
68 fScanlineDecoder.reset(NULL);
69 if (!rewindIfNeeded()) {
70 return NULL;
71 }
72 fScanlineDecoder.reset(this->onGetScanlineDecoder(dstInfo));
73 return fScanlineDecoder.get();
74}