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  }