skia image lib
1.SkImage decoded procedure
 SkImageDecoder.DecodeMemory/SkImageDecoder.DecodeFile
 SkImageDecoder.DecodeStream
 SkImageDecoder.decode
 SkImageDecoder.onDecode
 SkJPEGImageDecoder.onDecode(SkImageDecoder_libjpeg.cpp)
 SkImageDecoder.return_flase(error)
 
 
 2.factory mode
 a.client use abs product in it's code.
 client set the product to a specific one before use it.
 b.client use the factory to get a specific product.
 the key point is how we can get a specific product from the factory.
 there are two imporant points here. first we should pass a parameter in;
 second, how we can get different factory from the parameter.
 
 
 3.SkImageDecoder's factory
 in SkImageDecoder::DecodeStream, call
 SkImageDecoder* codec = SkImageDecoder::Factory(stream);
 to get a concrete ImageDecoder.
 a. in SkImageDecoder_Factory.cpp
- const DecodeReg* curr = DecodeReg::Head();
- while (curr) {
- codec = curr->factory()(stream);
- // we rewind here, because we promise later when we call "decode", that
- // the stream will be at its beginning.
- stream->rewind();
- if (codec) {
- return codec;
- }
- curr = curr->next();
- }
 Factory use DecodeReg class, traversal a DecodeReg list
 use "codec = curr->factory()(stream);" to find the decoder that match the stream.
 
 
 b.how does curr->factory()(stream) works?
 1)SkTRegistry defined in SkTRegistry.h
 typedef SkTRegistry<SkImageDecoder*, SkStream*> DecodeReg;
 //template class with two class parameters, first is SkImageDecoder, second is SKStream.
 Factory factory() const { return fFact; }
 Factory      fFact;
 template <typename T, typename P> class SkTRegistry :{
 typedef T (*Factory)(P);...}
 so curr->factory() will call a function pointer, input the SKStream and return SkImaageDecoer.
 2)how is the pointer assigned?
 SkTRegistry(Factory fact) {fFact = fact;...}
 in the constructor function.
 3)when is it called?
 in every concrete factory we define the factory.
 static SkTRegistry<SkImageDecoder*, SkStream*> gReg(Factory);
 static SkTRegistry<SkImageDecoder*, SkStream*> gReg(Factory);
 static SkTRegistry<SkImageDecoder*, SkStream*> gReg(Factory);
 static SkTRegistry<SkImageDecoder*, SkStream*> gDReg(DFactory);
 static SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> gEReg(EFactory);
 static SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> gEReg(sk_libpng_efactory);
 static SkTRegistry<SkImageDecoder*, SkStream*> gDReg(sk_libpng_dfactory);
 static SkTRegistry<SkImageDecoder*, SkStream*> gDReg(DFactory);
 static SkTRegistry<SkImageDecoder*, SkStream*> gReg(Factory);
 so we will call every decoder's Factory() when traversal the list and return the factory we want.
 4)how is the coder above added in called when we just call curr->factory?
 in SkImageDecoder_empty.cpp
- SkImageDecoder* SkImageDecoder::Factory(SkStream* stream) {
- for (size_t i = 0; i < SK_ARRAY_COUNT(gPairs); i++) {
- SkImageDecoder* codec = gPairs[i].fProc(stream);
- stream->rewind();
- if (NULL != codec) {
- return codec;
- }
- }
- return NULL;
- }
 
 add every in and call it.
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号