github.com/cellofellow/gopkg@v0.0.0-20140722061823-eec0544a62ad/image/jxr/jxrlib/src/jxr_decode.c (about) 1 // Copyright 2014 <chaishushan{AT}gmail.com>. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 #include "jxr.h" 6 #include "jxr_private.h" 7 8 struct jxr_decoder_t { 9 const void* pType; 10 PKFactory* pFactory; 11 PKImageDecode* pDecoder; 12 struct WMPStream* pStream; 13 int width; 14 int height; 15 int channels; 16 int depth; 17 jxr_data_type_t dataType; 18 }; 19 20 static const char jxr_decoder_type[] = "jxr_decoder_t"; 21 22 jxr_decoder_t* jxr_decoder_new() { 23 jxr_decoder_t* p = (jxr_decoder_t*)calloc(1, sizeof(*p)); 24 if(!p) return NULL; 25 26 p->pType = jxr_decoder_type; 27 if(Failed(PKCreateFactory(&p->pFactory, PK_SDK_VERSION))) { 28 jxr_decoder_delete(p); 29 return NULL; 30 } 31 if(Failed(PKImageDecode_Create_WMP(&p->pDecoder))) { 32 jxr_decoder_delete(p); 33 return NULL; 34 } 35 return p; 36 } 37 38 void jxr_decoder_delete(jxr_decoder_t* p) { 39 if(p == NULL || p->pType != jxr_decoder_type) { 40 fprintf(stderr, "jxr: jxr_decoder_delete, invalid jxr_decoder_t type!"); 41 abort(); 42 } 43 44 if(p->pDecoder != NULL) { 45 p->pDecoder->Release(&p->pDecoder); 46 p->pDecoder = NULL; 47 } 48 if(p->pStream != NULL) { 49 p->pStream->Close(&p->pStream); 50 p->pStream = NULL; 51 } 52 if(p->pFactory != NULL) { 53 p->pFactory->Release(&p->pFactory); 54 p->pFactory = NULL; 55 } 56 p->pType = NULL; 57 } 58 59 jxr_bool_t jxr_decoder_init(jxr_decoder_t* p, const char* data, int size) { 60 if(p == NULL || p->pType != jxr_decoder_type) { 61 fprintf(stderr, "jxr: jxr_decoder_init, invalid jxr_decoder_t type!"); 62 abort(); 63 } 64 65 // close old stream 66 if(p->pStream != NULL) { 67 p->pStream->Close(&p->pStream); 68 p->pStream = NULL; 69 } 70 p->width = 0; 71 p->height = 0; 72 p->channels = 0; 73 p->depth = 0; 74 p->dataType = jxr_unsigned; 75 76 // create new stream 77 if(Failed(p->pFactory->CreateStreamFromMemory(&p->pStream, (void*)data, size))) { 78 return jxr_false; 79 } 80 if(Failed(p->pDecoder->Initialize(p->pDecoder, p->pStream))) { 81 return jxr_false; 82 } 83 84 // parse image format 85 if(!jxr_parse_format_guid(&(p->pDecoder->guidPixFormat), &p->channels, &p->depth, &p->dataType)) { 86 return jxr_false; 87 } 88 p->width = (int)(p->pDecoder->uWidth); 89 p->height = (int)(p->pDecoder->uHeight); 90 return jxr_true; 91 } 92 93 int jxr_decoder_width(jxr_decoder_t* p) { 94 if(p == NULL || p->pType != jxr_decoder_type) { 95 fprintf(stderr, "jxr: jxr_decoder_width, invalid jxr_decoder_t type!"); 96 abort(); 97 } 98 return p->width; 99 } 100 101 int jxr_decoder_height(jxr_decoder_t* p) { 102 if(p == NULL || p->pType != jxr_decoder_type) { 103 fprintf(stderr, "jxr: jxr_decoder_height, invalid jxr_decoder_t type!"); 104 abort(); 105 } 106 return p->height; 107 } 108 109 int jxr_decoder_channels(jxr_decoder_t* p) { 110 if(p == NULL || p->pType != jxr_decoder_type) { 111 fprintf(stderr, "jxr: jxr_decoder_channels, invalid jxr_decoder_t type!"); 112 abort(); 113 } 114 return p->channels; 115 } 116 117 int jxr_decoder_depth(jxr_decoder_t* p) { 118 if(p == NULL || p->pType != jxr_decoder_type) { 119 fprintf(stderr, "jxr: jxr_decoder_depth, invalid jxr_decoder_t type!"); 120 abort(); 121 } 122 return p->depth; 123 } 124 125 int jxr_decoder_data_type(jxr_decoder_t* p) { 126 if(p == NULL || p->pType != jxr_decoder_type) { 127 fprintf(stderr, "jxr: jxr_decoder_data_type, invalid jxr_decoder_t type!"); 128 abort(); 129 } 130 return p->dataType; 131 } 132 133 jxr_bool_t jxr_decoder_decode(jxr_decoder_t* p, const jxr_rect_t* r, char* buf, int stride) { 134 PKRect rect; 135 ERR err = WMP_errSuccess; 136 137 if(p == NULL || p->pType != jxr_decoder_type) { 138 fprintf(stderr, "jxr: jxr_decoder_decode, invalid jxr_decoder_t type!"); 139 abort(); 140 } 141 142 if(buf == NULL) { 143 return jxr_false; 144 } 145 if(p->width <= 0 || p->height <= 0 || p->channels <= 0 || p->depth <= 0) { 146 return jxr_false; 147 } 148 149 // set stride size 150 if(stride <= 0) { 151 stride = (p->width)*(p->channels)*(p->depth)/8; 152 } 153 if(stride < ((p->width)*(p->channels)*(p->depth)/8)) { 154 return jxr_false; 155 } 156 157 if(r != NULL) { 158 rect.X = r->x; 159 rect.Y = r->y; 160 rect.Width = r->width; 161 rect.Height = r->height; 162 } else { 163 rect.X = 0; 164 rect.Y = 0; 165 rect.Width = p->width; 166 rect.Height = p->height; 167 } 168 169 // decode image data 170 p->pDecoder->WMP.wmiI.bRGB = 1; // use RGB order 171 err = p->pDecoder->Copy(p->pDecoder, &rect, buf, stride); 172 return Failed(err)? jxr_false: jxr_true; 173 }