1 /* libs/graphics/ports/SkImageDecoder_Factory.cpp
2 **
3 ** Copyright 2006, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
18 #include "SkImageDecoder.h"
19 #include "SkMovie.h"
20 #include "SkStream.h"
21 #include "SkTRegistry.h"
22
23 typedef SkTRegistry<SkImageDecoder*, SkStream*> DecodeReg;
24
25 // N.B. You can't use "DecodeReg::gHead here" due to complex C++
26 // corner cases.
27 template DecodeReg* SkTRegistry<SkImageDecoder*, SkStream*>::gHead;
28
29 #ifdef SK_ENABLE_LIBPNG
30 extern SkImageDecoder* sk_libpng_dfactory(SkStream*);
31 #endif
32
Factory(SkStream * stream)33 SkImageDecoder* SkImageDecoder::Factory(SkStream* stream) {
34 SkImageDecoder* codec = NULL;
35 const DecodeReg* curr = DecodeReg::Head();
36 while (curr) {
37 codec = curr->factory()(stream);
38 // we rewind here, because we promise later when we call "decode", that
39 // the stream will be at its beginning.
40 stream->rewind();
41 if (codec) {
42 return codec;
43 }
44 curr = curr->next();
45 }
46 #ifdef SK_ENABLE_LIBPNG
47 codec = sk_libpng_dfactory(stream);
48 stream->rewind();
49 if (codec) {
50 return codec;
51 }
52 #endif
53 return NULL;
54 }
55
56 /////////////////////////////////////////////////////////////////////////
57
58 typedef SkTRegistry<SkMovie*, SkStream*> MovieReg;
59
DecodeStream(SkStream * stream)60 SkMovie* SkMovie::DecodeStream(SkStream* stream) {
61 const MovieReg* curr = MovieReg::Head();
62 while (curr) {
63 SkMovie* movie = curr->factory()(stream);
64 if (movie) {
65 return movie;
66 }
67 // we must rewind only if we got NULL, since we gave the stream to the
68 // movie, who may have already started reading from it
69 stream->rewind();
70 curr = curr->next();
71 }
72 return NULL;
73 }
74