github.com/cellofellow/gopkg@v0.0.0-20140722061823-eec0544a62ad/image/jxr/jxrlib/src/jxr_encode.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_encoder_t { 9 const void* pType; 10 PKFactory* pFactory; 11 PKImageEncode* pEncoder; 12 struct WMPStream* pStream; 13 CWMIStrCodecParam wmiSCP; 14 const char* data; 15 int dataSize; 16 int stride; 17 int width; 18 int height; 19 int channels; 20 int depth; 21 int quality; 22 jxr_data_type_t dataType; 23 size_t destSize; 24 }; 25 26 static const char jxr_encoder_type[] = "jxr_encoder_t"; 27 28 jxr_encoder_t* jxr_encoder_new() { 29 jxr_encoder_t* p = (jxr_encoder_t*)calloc(1, sizeof(*p)); 30 if(!p) return NULL; 31 32 p->pType = jxr_encoder_type; 33 if(Failed(PKCreateFactory(&p->pFactory, PK_SDK_VERSION))) { 34 jxr_encoder_delete(p); 35 return NULL; 36 } 37 if(Failed(PKImageEncode_Create_WMP(&p->pEncoder))) { 38 jxr_encoder_delete(p); 39 return NULL; 40 } 41 return p; 42 } 43 44 void jxr_encoder_delete(jxr_encoder_t* p) { 45 if(p == NULL || p->pType != jxr_encoder_type) { 46 fprintf(stderr, "jxr: jxr_encoder_delete, invalid jxr_decoder_t type!"); 47 abort(); 48 } 49 50 if(p->pEncoder != NULL) { 51 p->pEncoder->Release(&p->pEncoder); 52 p->pEncoder = NULL; 53 } 54 if(p->pStream != NULL) { 55 p->pStream->Close(&p->pStream); 56 p->pStream = NULL; 57 } 58 if(p->pFactory != NULL) { 59 p->pFactory->Release(&p->pFactory); 60 p->pFactory = NULL; 61 } 62 p->pType = NULL; 63 } 64 65 jxr_bool_t jxr_encoder_init(jxr_encoder_t* p, 66 const char* data, int size, int stride, 67 int width, int height, int channels, int depth, 68 int quality, jxr_data_type_t type 69 ) { 70 const PKPixelFormatGUID* fmt = NULL; 71 72 if(p == NULL || p->pType != jxr_encoder_type) { 73 fprintf(stderr, "jxr: jxr_encoder_init, invalid jxr_decoder_t type!"); 74 abort(); 75 } 76 77 // lookup best match format 78 if(!jxr_golden_format(channels, depth, type, &fmt)) { 79 return jxr_false; 80 } 81 if(Failed(p->pEncoder->SetPixelFormat(p->pEncoder, *fmt))) { 82 return jxr_false; 83 } 84 85 // set image size 86 if(Failed(p->pEncoder->SetSize(p->pEncoder, width, height))) { 87 return jxr_false; 88 } 89 90 p->data = data; 91 p->dataSize = size; 92 p->stride = stride; 93 94 p->width = width; 95 p->height = height; 96 p->channels = channels; 97 p->depth = depth; 98 p->quality = quality; 99 p->dataType = type; 100 p->destSize = 0; 101 102 return jxr_true; 103 } 104 105 jxr_bool_t jxr_encoder_need_buffer_size(jxr_encoder_t* p, int* size) { 106 struct WMPStream* pNilStream = NULL; 107 108 if(p->destSize == 0) { 109 // create discard stream 110 if(Failed(CreateWS_Discard(&pNilStream))) { 111 return jxr_false; 112 } 113 if(Failed(p->pEncoder->Initialize(p->pEncoder, pNilStream, &p->wmiSCP, sizeof(p->wmiSCP)))) { 114 pNilStream->Close(&pNilStream); 115 return jxr_false; 116 } 117 118 { 119 // how to set quality ? 120 } 121 122 // try encode 123 if(Failed(p->pEncoder->WritePixels(p->pEncoder, p->height, (U8*)p->data, p->stride))) { 124 pNilStream->Close(&pNilStream); 125 return jxr_false; 126 } 127 if(Failed(pNilStream->GetPos(pNilStream, &p->destSize))) { 128 pNilStream->Close(&pNilStream); 129 return jxr_false; 130 } 131 132 pNilStream->Close(&pNilStream); 133 } 134 if(size != NULL) { 135 *size = p->destSize; 136 } 137 return jxr_true; 138 } 139 140 jxr_bool_t jxr_encoder_encode(jxr_encoder_t* p, char* buf, int buf_len, int* size) { 141 // create new stream 142 if(p->pStream == NULL) { 143 if(Failed(p->pFactory->CreateStreamFromMemory(&p->pStream, (void*)buf, buf_len))) { 144 return jxr_false; 145 } 146 } 147 148 // set output steam 149 if(Failed(p->pEncoder->Initialize(p->pEncoder, p->pStream, &p->wmiSCP, sizeof(p->wmiSCP)))) { 150 return jxr_false; 151 } 152 153 // how to set quality ? 154 { 155 // 156 } 157 158 // encode 159 if(Failed(p->pEncoder->WritePixels(p->pEncoder, p->height, (U8*)p->data, p->stride))) { 160 return jxr_false; 161 } 162 if(Failed(p->pStream->GetPos(p->pStream, &p->destSize))) { 163 return jxr_false; 164 } 165 if(size != NULL) { 166 *size = p->destSize; 167 } 168 169 return jxr_true; 170 }