blob: 0411e44069e32cd15e7e218ac2100eb6649e6080 [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"
msarett15bfd072015-03-24 12:24:27 -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 },
msarett15bfd072015-03-24 12:24:27 -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)
52 , fInfo(info)
scroggof24f2242015-03-03 08:59:20 -080053 , fStream(stream)
54 , fNeedsRewind(false)
55{}
56
57bool SkCodec::rewindIfNeeded() {
58 // Store the value of fNeedsRewind so we can update it. Next read will
59 // require a rewind.
60 const bool neededRewind = fNeedsRewind;
61 fNeedsRewind = true;
62 return !neededRewind || fStream->rewind();
63}