Graphics framework for GR-PEACH. When you use this program, we judge you have agreed to the following contents. https://developer.mbed.org/teams/Renesas/wiki/About-LICENSE
Dependents: ImageZoomInout_Sample ImageRotaion_Sample ImageScroll_Sample GR-PEACH_LCD_4_3inch_Save_to_USB ... more
JPEG_Coverter.cpp
00001 /******************************************************************************* 00002 * DISCLAIMER 00003 * This software is supplied by Renesas Electronics Corporation and is only 00004 * intended for use with Renesas products. No other uses are authorized. This 00005 * software is owned by Renesas Electronics Corporation and is protected under 00006 * all applicable laws, including copyright laws. 00007 * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING 00008 * THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT 00009 * LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE 00010 * AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. 00011 * TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS 00012 * ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE 00013 * FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR 00014 * ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE 00015 * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 00016 * Renesas reserves the right, without notice, to make changes to this software 00017 * and to discontinue the availability of this software. By using this software, 00018 * you agree to the additional terms and conditions found by accessing the 00019 * following link: 00020 * http://www.renesas.com/disclaimer* 00021 * Copyright (C) 2015 Renesas Electronics Corporation. All rights reserved. 00022 *******************************************************************************/ 00023 00024 /**************************************************************************//** 00025 * @file jpeg_coverter.cpp 00026 * @version 1.00 00027 * $Rev: 1 $ 00028 * $Date:: 2015-08-06 16:33:52 +0900#$ 00029 * @brief Decodes JPEG data and encodes to JPEG data 00030 ******************************************************************************/ 00031 00032 /****************************************************************************** 00033 Includes <System Includes> , "Project Includes" 00034 ******************************************************************************/ 00035 #include <string.h> 00036 #include <stdio.h> 00037 #include "rtos.h" 00038 #include "r_typedefs.h" 00039 #include "r_jcu_api.h" 00040 #include "JPEG_Converter.h" 00041 #include "converter_wrapper.h" 00042 00043 /****************************************************************************** 00044 Typedef definitions 00045 ******************************************************************************/ 00046 00047 /****************************************************************************** 00048 Macro definitions 00049 ******************************************************************************/ 00050 #define QUANTIZATION_TABLE_SIZE (64u) 00051 #define HUFFMAN_TABLE_DC_SIZE (28u) 00052 #define HUFFMAN_TABLE_AC_SIZE (178u) 00053 #define JPEG_HEADER_LETTER_1 (0xFFu) 00054 #define JPEG_HEADER_LETTER_2 (0xD8u) 00055 #define ALPHA_VAL_MAX (0xFF) 00056 #define LOC_KIND_COLOR_FORMAT (3u) 00057 #define QUANTIZATION_TABLE_NUM (2) 00058 00059 #define ENC_SIZE_MAX (1024 * 30) 00060 #define MASK_8BYTE (0xFFFFFFF8) 00061 00062 /*[HuffmanTable_Y_DC]*/ 00063 /* Example written in ITU-T T81 specification */ 00064 static const uint8_t csaDefaultHuffmanTable_Y_DC[HUFFMAN_TABLE_DC_SIZE] = { 00065 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00066 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B 00067 }; 00068 00069 /*[HuffmanTable_C_DC]*/ 00070 /* Example written in ITU-T T81 specification */ 00071 static const uint8_t csaDefaultHuffmanTable_C_DC[HUFFMAN_TABLE_DC_SIZE] = { 00072 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 00073 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B 00074 }; 00075 00076 /*[HuffmanTable_Y_AC]*/ 00077 /* Example written in ITU-T T81 specification */ 00078 static const uint8_t csaDefaultHuffmanTable_Y_AC[HUFFMAN_TABLE_AC_SIZE] = { 00079 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 00080 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 00081 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 00082 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 00083 0x29, 0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 00084 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 00085 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 00086 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 00087 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 00088 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 00089 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 00090 0xF9, 0xFA 00091 }; 00092 00093 /*[HuffmanTable_C_AC]*/ 00094 /* Example written in ITU-T T81 specification */ 00095 static const uint8_t csaDefaultHuffmanTable_C_AC[HUFFMAN_TABLE_AC_SIZE] = { 00096 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 00097 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 00098 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33, 0x52, 0xF0, 00099 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16, 0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 00100 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 00101 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 00102 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 00103 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 00104 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 00105 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 00106 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 00107 0xF9, 0xFA 00108 }; 00109 00110 typedef void (JPEG_CallbackFunc_t)(JPEG_Converter::jpeg_conv_error_t err_code); 00111 00112 static uint32_t driver_ac_count = 0; 00113 static bool jcu_error_flag; 00114 static JPEG_CallbackFunc_t* pJPEG_ConverterCallback; 00115 Semaphore jpeg_converter_semaphore(1); 00116 #if defined(__ICCARM__) 00117 #pragma data_alignment=32 00118 static uint8_t QuantizationTable_Y[QUANTIZATION_TABLE_SIZE]@ ".mirrorram"; 00119 #pragma data_alignment=32 00120 static uint8_t QuantizationTable_C[QUANTIZATION_TABLE_SIZE]@ ".mirrorram"; 00121 #else 00122 static uint8_t QuantizationTable_Y[QUANTIZATION_TABLE_SIZE]__attribute((section("NC_BSS"),aligned(32))); 00123 static uint8_t QuantizationTable_C[QUANTIZATION_TABLE_SIZE]__attribute((section("NC_BSS"),aligned(32))); 00124 #endif 00125 00126 /**************************************************************************//** 00127 * @brief Set encode quality 00128 * @param[in] uint8_t qual : Encode quality (1 <= qual <= 100) 00129 * @retval error code 00130 ******************************************************************************/ 00131 JPEG_Converter::jpeg_conv_error_t 00132 JPEG_Converter::SetQuality(const uint8_t qual) { 00133 uint8_t* pqs[QUANTIZATION_TABLE_NUM]; 00134 const uint8_t* pqb[QUANTIZATION_TABLE_NUM]; 00135 uint8_t* ptqs; 00136 const uint8_t* ptqb; 00137 int_t temp; 00138 int_t i; 00139 int_t j; 00140 00141 /* ITU-T Recommendation T.81 "K.1 Quantization tables for luminance and chrominance components" */ 00142 /* Table K.1 - Luminance quantization table */ 00143 const uint8_t quantization_table_y_50[QUANTIZATION_TABLE_SIZE] = { 00144 16, 11, 10, 16, 24, 40, 51, 61, 00145 12, 12, 14, 19, 26, 58, 60, 55, 00146 14, 13, 16, 24, 40, 57, 69, 56, 00147 14, 17, 22, 29, 51, 87, 80, 62, 00148 18, 22, 37, 56, 68, 109, 103, 77, 00149 24, 35, 55, 64, 81, 104, 113, 92, 00150 49, 64, 78, 87, 103, 121, 120, 101, 00151 72, 92, 95, 98, 112, 100, 103, 99 00152 }; 00153 00154 /* Table K.2 - Chrominance quantization table */ 00155 const uint8_t quantization_table_c_50[QUANTIZATION_TABLE_SIZE] = { 00156 17, 18, 24, 47, 99, 99, 99, 99, 00157 18, 21, 26, 66, 99, 99, 99, 99, 00158 24, 26, 56, 99, 99, 99, 99, 99, 00159 47, 66, 99, 99, 99, 99, 99, 99, 00160 99, 99, 99, 99, 99, 99, 99, 99, 00161 99, 99, 99, 99, 99, 99, 99, 99, 00162 99, 99, 99, 99, 99, 99, 99, 99, 00163 99, 99, 99, 99, 99, 99, 99, 99 00164 }; 00165 00166 if (((int_t)qual < 1) || ((int_t)qual > 100)) { 00167 return JPEG_CONV_PARAM_RANGE_ERR ; 00168 } 00169 00170 pqs[0] = QuantizationTable_Y; 00171 pqb[0] = quantization_table_y_50; 00172 pqs[1] = QuantizationTable_C; 00173 pqb[1] = quantization_table_c_50; 00174 00175 for (j = 0; j < QUANTIZATION_TABLE_NUM; j++) { 00176 ptqs = pqs[j]; 00177 ptqb = pqb[j]; 00178 if ((int_t)qual < 50) { 00179 for (i = 0; i < QUANTIZATION_TABLE_SIZE; i++) { 00180 temp = (((int_t)ptqb[i] * 100) + (int_t)qual) / (2 * (int_t)qual); 00181 if (temp == 0) { 00182 temp = 1; 00183 } 00184 if (temp > 255) { 00185 temp = 255; 00186 } 00187 ptqs[i] = (uint8_t)temp; 00188 } 00189 } else { 00190 for (i = 0; i < QUANTIZATION_TABLE_SIZE; i++) { 00191 temp = (((200 - (2 * (int_t)qual)) * (int_t)ptqb[i]) + 50) / 100; 00192 if (temp == 0) { 00193 temp = 1; 00194 } 00195 if (temp > 255) { 00196 temp = 255; 00197 } 00198 ptqs[i] = (uint8_t)temp; 00199 } 00200 } 00201 } 00202 00203 return JPEG_CONV_OK ; 00204 } 00205 00206 00207 /**************************************************************************//** 00208 * @brief Callback function from JCU async mode 00209 * @param[in] mbed_jcu_err_t err_code : JCU result 00210 * @retval None 00211 ******************************************************************************/ 00212 void JPEG_CallbackFunction(mbed_jcu_err_t err_code) { 00213 if (pJPEG_ConverterCallback != NULL) { 00214 pJPEG_ConverterCallback((JPEG_Converter::jpeg_conv_error_t)err_code); 00215 } 00216 if (err_code != MBED_JCU_E_OK ) { 00217 jcu_error_flag = true; 00218 } 00219 jpeg_converter_semaphore.release(); // RELEASE 00220 } /* End of callback function method () */ 00221 00222 /**************************************************************************//** 00223 * @brief Constructor of the JPEG_Converter class 00224 * @param[in] None 00225 * @retval None 00226 ******************************************************************************/ 00227 JPEG_Converter::JPEG_Converter(void) { 00228 jcu_errorcode_t jcu_error; 00229 00230 if (driver_ac_count == 0) { 00231 SetQuality(75); 00232 jcu_error = R_JCU_Initialize(NULL); 00233 if (jcu_error == JCU_ERROR_OK) { 00234 driver_ac_count++; 00235 jcu_error_flag = false; 00236 } 00237 } else { 00238 driver_ac_count++; 00239 } 00240 } /* End of constructor method () */ 00241 00242 /**************************************************************************//** 00243 * @brief Destructor of the JPEG_Converter class 00244 * @param[in] None 00245 * @retval None 00246 ******************************************************************************/ 00247 JPEG_Converter::~JPEG_Converter(void) { 00248 if (driver_ac_count > 0) { 00249 driver_ac_count--; 00250 if (driver_ac_count == 0) { 00251 (void)R_JCU_Terminate(); 00252 } 00253 } 00254 } /* End of destructor method () */ 00255 00256 /**************************************************************************//** 00257 * @brief JPEG data decode to bitmap 00258 * @param[in] void* pJpegBuff : Input JPEG data address 00259 * @param[in/out] bitmap_buff_info_t* psOutputBuff : Output bitmap data address 00260 * @retval error code 00261 ******************************************************************************/ 00262 JPEG_Converter::jpeg_conv_error_t 00263 JPEG_Converter::decode(void* pJpegBuff, bitmap_buff_info_t* psOutputBuff) { 00264 decode_options_t Options; 00265 00266 return (decode(pJpegBuff, psOutputBuff, &Options)); 00267 } /* End of method decode() */ 00268 00269 /**************************************************************************//** 00270 * @brief JPEG data decode to bitmap 00271 * @param[in] void* pJpegBuff : Input JPEG data address 00272 * @param[in/out] bitmap_buff_info_t* psOutputBuff : Output bitmap data address 00273 * @param[in] decode_options_t* pOptions : Decode option(Optional) 00274 * @retval error code 00275 ******************************************************************************/ 00276 JPEG_Converter::jpeg_conv_error_t 00277 JPEG_Converter::decode(void* pJpegBuff, bitmap_buff_info_t* psOutputBuff, decode_options_t* pOptions) { 00278 jpeg_conv_error_t e; 00279 jcu_errorcode_t jcu_error; 00280 jcu_decode_param_t decode; 00281 jcu_buffer_param_t buffer; 00282 uint8_t* pBuff = (uint8_t *)pJpegBuff; 00283 const jcu_async_status_t* status; 00284 jcu_image_info_t image_info; 00285 bool mutex_release = false; 00286 00287 // Check JCU initialized 00288 if (driver_ac_count > 0) { 00289 size_t calc_height; 00290 size_t calc_width; 00291 00292 calc_height = psOutputBuff->height * (2 ^ pOptions->vertical_sub_sampling); 00293 calc_width = psOutputBuff->width * (2 ^ pOptions->horizontal_sub_sampling); 00294 00295 // Check input address 00296 if ((pJpegBuff == NULL) || (psOutputBuff == NULL) || (pOptions == NULL)) { 00297 e = JPEG_CONV_PARAM_ERR ; // Input address error 00298 goto fin; 00299 } 00300 // Check JPEG header 00301 if (((uint32_t)(pBuff[0]) != JPEG_HEADER_LETTER_1) || 00302 ((uint32_t)(pBuff[1]) != JPEG_HEADER_LETTER_2)) { 00303 e = JPEG_CONV_FORMA_ERR ; // JPEG data is not in ROM 00304 goto fin; 00305 } 00306 // JCU Error reset 00307 if (jcu_error_flag == true) { 00308 (void)R_JCU_Terminate(); 00309 (void)R_JCU_Initialize(NULL); 00310 jcu_error_flag = false; 00311 } 00312 // Get mutex 00313 if (pOptions->p_DecodeCallBackFunc == NULL) { 00314 jpeg_converter_semaphore.wait(0xFFFFFFFFuL); // WAIT 00315 } else { 00316 if (!jpeg_converter_semaphore.wait(0)) { 00317 e = JPEG_CONV_BUSY ; // Busy 00318 goto fin; 00319 } 00320 } 00321 // Select decode 00322 jcu_error = R_JCU_SelectCodec( JCU_DECODE ); 00323 if (jcu_error != JCU_ERROR_OK) { 00324 e = JPEG_CONV_JCU_ERR ; 00325 mutex_release = true; 00326 goto fin; 00327 } 00328 00329 buffer.source.swapSetting = JCU_SWAP_LONG_WORD_AND_WORD_AND_BYTE; 00330 buffer.source.address = (uint32_t *)pBuff; 00331 buffer.lineOffset = (int16_t)psOutputBuff->width ; 00332 buffer.destination.address = (uint32_t *)psOutputBuff->buffer_address ; 00333 decode.decodeFormat = (jcu_decode_format_t)psOutputBuff->format ; 00334 buffer.destination.swapSetting = (jcu_swap_t)pOptions->output_swapsetting; 00335 decode.outputCbCrOffset = (jcu_cbcr_offset_t)pOptions->output_cb_cr_offset; 00336 decode.alpha = pOptions->alpha; 00337 decode.horizontalSubSampling = (jcu_sub_sampling_t)pOptions->horizontal_sub_sampling; 00338 decode.verticalSubSampling = (jcu_sub_sampling_t)pOptions->vertical_sub_sampling; 00339 00340 jcu_error = R_JCU_SetDecodeParam(&decode, &buffer); 00341 if (jcu_error != JCU_ERROR_OK) { 00342 e = JPEG_CONV_FORMA_ERR ; 00343 mutex_release = true; 00344 jcu_error_flag = false; 00345 goto fin; 00346 } 00347 00348 if (pOptions->check_jpeg_format != false) { 00349 jcu_error = R_JCU_SetPauseForImageInfo(true); 00350 if (jcu_error != JCU_ERROR_OK) { 00351 e = JPEG_CONV_JCU_ERR ; 00352 mutex_release = true; 00353 jcu_error_flag = false; 00354 goto fin; 00355 } 00356 } 00357 if (pOptions->p_DecodeCallBackFunc == NULL) { 00358 jcu_error = R_JCU_Start(); 00359 mutex_release = true; 00360 if (jcu_error != JCU_ERROR_OK) { 00361 e = JPEG_CONV_JCU_ERR ; 00362 jcu_error_flag = false; 00363 goto fin; 00364 } 00365 if (pOptions->check_jpeg_format != false) { 00366 R_JCU_GetAsyncStatus( &status ); 00367 if (status -> IsPaused == false) { 00368 e = JPEG_CONV_JCU_ERR ; 00369 jcu_error_flag = false; 00370 goto fin; 00371 } 00372 if ((status->SubStatusFlags & JCU_SUB_INFOMATION_READY) == 0) { 00373 e = JPEG_CONV_JCU_ERR ; 00374 jcu_error_flag = false; 00375 goto fin; 00376 } 00377 jcu_error = R_JCU_GetImageInfo( &image_info ); 00378 if (jcu_error != JCU_ERROR_OK) { 00379 e = JPEG_CONV_JCU_ERR ; 00380 jcu_error_flag = false; 00381 goto fin; 00382 } 00383 if ((image_info.width == 0u) || (image_info.height == 0u) || 00384 (image_info.width > calc_width) || 00385 (image_info.height > calc_height)) { 00386 e = JPEG_CONV_FORMA_ERR ; 00387 jcu_error_flag = false; 00388 goto fin; 00389 } 00390 if ((image_info.encodedFormat != JCU_JPEG_YCbCr444) && 00391 (image_info.encodedFormat != JCU_JPEG_YCbCr422) && 00392 (image_info.encodedFormat != JCU_JPEG_YCbCr420) && 00393 (image_info.encodedFormat != JCU_JPEG_YCbCr411)) { 00394 e = JPEG_CONV_FORMA_ERR ; 00395 jcu_error_flag = false; 00396 goto fin; 00397 } 00398 jcu_error = R_JCU_Continue(JCU_IMAGE_INFO); 00399 if (jcu_error != JCU_ERROR_OK) { 00400 e = JPEG_CONV_JCU_ERR ; 00401 jcu_error_flag = false; 00402 goto fin; 00403 } 00404 } 00405 } else { 00406 pJPEG_ConverterCallback = pOptions->p_DecodeCallBackFunc; 00407 jcu_error = R_wrpper_set_decode_callback((mbed_CallbackFunc_t*)JPEG_CallbackFunction, (size_t)calc_width, calc_height); 00408 if (jcu_error != JCU_ERROR_OK) { 00409 e = JPEG_CONV_JCU_ERR ; 00410 mutex_release = true; 00411 goto fin; 00412 } 00413 } 00414 e = JPEG_CONV_OK ; 00415 } 00416 else 00417 { 00418 e = JPEG_CONV_JCU_ERR ; 00419 } 00420 fin: 00421 if (mutex_release == true) { 00422 jpeg_converter_semaphore.release(); // RELEASE 00423 } 00424 00425 return e; 00426 } /* End of method decode() */ 00427 00428 00429 /**************************************************************************//** 00430 * @brief Bitmap data encode to JPEG 00431 * @param[in] bitmap_buff_info_t* psInputBuff : Input bitmap data address 00432 * @param[out] void* pJpegBuff : Output JPEG data address 00433 * @param[out] size_t* pEncodeSize : Encode size address 00434 * @retval error code 00435 ******************************************************************************/ 00436 JPEG_Converter::jpeg_conv_error_t 00437 JPEG_Converter::encode(bitmap_buff_info_t* psInputBuff, void* pJpegBuff, size_t* pEncodeSize ) { 00438 encode_options_t Options; 00439 00440 return (encode(psInputBuff, pJpegBuff, pEncodeSize, &Options)); 00441 } /* End of method encode() */ 00442 00443 00444 /**************************************************************************//** 00445 * @brief Bitmap data encode to JPEG 00446 * @param[in] bitmap_buff_info_t* psInputBuff : Input bitmap data address 00447 * @param[out] void* pJpegBuff : Output JPEG data address 00448 * @param[out] size_t* pEncodeSize : Encode size address 00449 * @param[in] encode_options_t* pOptions : Encode option(Optional) 00450 * @retval error code 00451 ******************************************************************************/ 00452 JPEG_Converter::jpeg_conv_error_t 00453 JPEG_Converter::encode(bitmap_buff_info_t* psInputBuff, void* pJpegBuff, size_t* pEncodeSize, encode_options_t* pOptions ) { 00454 00455 jpeg_conv_error_t e; 00456 jcu_errorcode_t jcu_error; 00457 jcu_buffer_param_t buffer; 00458 uint8_t* TableAddress; 00459 jcu_encode_param_t encode; 00460 jcu_count_mode_param_t count_para; 00461 int32_t encode_count; 00462 int32_t size_max_count = 1; 00463 size_t BufferSize = pOptions->encode_buff_size ; 00464 const jcu_async_status_t* status; 00465 bool mutex_release = false; 00466 00467 // Check JCU initialized 00468 if (driver_ac_count > 0) { 00469 // Check input address 00470 if ((pJpegBuff == NULL) || (psInputBuff == NULL) || (pEncodeSize == NULL)) { 00471 e = JPEG_CONV_PARAM_ERR ; // Input address error 00472 goto fin; 00473 } 00474 // JCU Error reset 00475 if (jcu_error_flag == true) { 00476 (void)R_JCU_Terminate(); 00477 (void)R_JCU_Initialize(NULL); 00478 jcu_error_flag = false; 00479 } 00480 // Get mutex 00481 if ( pOptions->p_EncodeCallBackFunc == NULL ) { 00482 jpeg_converter_semaphore.wait(0xFFFFFFFFuL); // WAIT 00483 } else { 00484 if (!jpeg_converter_semaphore.wait(0)) { 00485 e = JPEG_CONV_BUSY ; // Busy 00486 goto fin; 00487 } 00488 } 00489 // Select encode 00490 jcu_error = R_JCU_SelectCodec(JCU_ENCODE); 00491 if (jcu_error != JCU_ERROR_OK) { 00492 e = JPEG_CONV_JCU_ERR ; 00493 mutex_release = true; 00494 goto fin; 00495 } 00496 /* Set tables */ 00497 if ( pOptions->quantization_table_Y != NULL ) { 00498 TableAddress = (uint8_t*)pOptions->quantization_table_Y ; 00499 } else { 00500 TableAddress = (uint8_t*)QuantizationTable_Y; 00501 } 00502 jcu_error = R_JCU_SetQuantizationTable( JCU_TABLE_NO_0, (uint8_t*)TableAddress ); 00503 if ( jcu_error != JCU_ERROR_OK ) { 00504 e = JPEG_CONV_PARAM_RANGE_ERR ; 00505 mutex_release = true; 00506 jcu_error_flag = true; 00507 goto fin; 00508 } 00509 if ( pOptions->quantization_table_C != NULL ) { 00510 TableAddress = (uint8_t*)pOptions->quantization_table_C ; 00511 } else { 00512 TableAddress = (uint8_t*)QuantizationTable_C; 00513 } 00514 jcu_error = R_JCU_SetQuantizationTable( JCU_TABLE_NO_1, (uint8_t*)TableAddress ); 00515 if ( jcu_error != JCU_ERROR_OK ) { 00516 e = JPEG_CONV_PARAM_RANGE_ERR ; 00517 mutex_release = true; 00518 jcu_error_flag = true; 00519 goto fin; 00520 } 00521 if ( pOptions->huffman_table_Y_DC != NULL ) { 00522 TableAddress = (uint8_t*)pOptions->huffman_table_Y_DC ; 00523 } else { 00524 TableAddress = (uint8_t*)csaDefaultHuffmanTable_Y_DC; 00525 } 00526 jcu_error = R_JCU_SetHuffmanTable( JCU_TABLE_NO_0, JCU_HUFFMAN_DC, (uint8_t*)TableAddress ); 00527 if ( jcu_error != JCU_ERROR_OK ) { 00528 e = JPEG_CONV_PARAM_RANGE_ERR ; 00529 mutex_release = true; 00530 jcu_error_flag = true; 00531 goto fin; 00532 } 00533 if ( pOptions->huffman_table_C_DC != NULL ) { 00534 TableAddress = (uint8_t*)pOptions->huffman_table_C_DC ; 00535 } else { 00536 TableAddress = (uint8_t*)csaDefaultHuffmanTable_C_DC; 00537 } 00538 jcu_error = R_JCU_SetHuffmanTable( JCU_TABLE_NO_1, JCU_HUFFMAN_DC, (uint8_t*)TableAddress ); 00539 if ( jcu_error != JCU_ERROR_OK ) { 00540 e = JPEG_CONV_PARAM_RANGE_ERR ; 00541 mutex_release = true; 00542 jcu_error_flag = true; 00543 goto fin; 00544 } 00545 if ( pOptions->huffman_table_Y_AC != NULL ) { 00546 TableAddress = (uint8_t*)pOptions->huffman_table_Y_AC ; 00547 } else { 00548 TableAddress = (uint8_t*)csaDefaultHuffmanTable_Y_AC; 00549 } 00550 jcu_error = R_JCU_SetHuffmanTable( JCU_TABLE_NO_0, JCU_HUFFMAN_AC, (uint8_t*)TableAddress ); 00551 if ( jcu_error != JCU_ERROR_OK ) { 00552 e = JPEG_CONV_PARAM_RANGE_ERR ; 00553 mutex_release = true; 00554 jcu_error_flag = true; 00555 goto fin; 00556 } 00557 if ( pOptions->huffman_table_C_AC != NULL ) { 00558 TableAddress = (uint8_t*)pOptions->huffman_table_C_AC ; 00559 } else { 00560 TableAddress = (uint8_t*)csaDefaultHuffmanTable_C_AC; 00561 } 00562 jcu_error = R_JCU_SetHuffmanTable( JCU_TABLE_NO_1, JCU_HUFFMAN_AC, (uint8_t*)TableAddress ); 00563 if ( jcu_error != JCU_ERROR_OK ) { 00564 e = JPEG_CONV_PARAM_RANGE_ERR ; 00565 mutex_release = true; 00566 jcu_error_flag = true; 00567 goto fin; 00568 } 00569 00570 // JPEG encode 00571 buffer.source.swapSetting = (jcu_swap_t)pOptions->input_swapsetting ; 00572 buffer.source.address = (uint32_t *)psInputBuff->buffer_address ; 00573 buffer.destination.swapSetting = JCU_SWAP_LONG_WORD_AND_WORD_AND_BYTE; 00574 buffer.destination.address = (uint32_t *)pJpegBuff; 00575 buffer.lineOffset = psInputBuff->width ; 00576 encode.encodeFormat = (jcu_jpeg_format_t)JCU_JPEG_YCbCr422; 00577 encode.QuantizationTable[ JCU_ELEMENT_Y ] = JCU_TABLE_NO_0; 00578 encode.QuantizationTable[ JCU_ELEMENT_Cb ] = JCU_TABLE_NO_1; 00579 encode.QuantizationTable[ JCU_ELEMENT_Cr ] = JCU_TABLE_NO_1; 00580 encode.HuffmanTable[ JCU_ELEMENT_Y ] = JCU_TABLE_NO_0; 00581 encode.HuffmanTable[ JCU_ELEMENT_Cb ] = JCU_TABLE_NO_1; 00582 encode.HuffmanTable[ JCU_ELEMENT_Cr ] = JCU_TABLE_NO_1; 00583 encode.DRI_value = pOptions->DRI_value ; 00584 if ( pOptions->width != 0 ) { 00585 encode.width = pOptions->width ; 00586 } else { 00587 encode.width = psInputBuff->width ; 00588 } 00589 if ( pOptions->height != 0 ) { 00590 encode.height = pOptions->height ; 00591 } else { 00592 encode.height = psInputBuff->height ; 00593 } 00594 encode.inputCbCrOffset = (jcu_cbcr_offset_t)pOptions->input_cb_cr_offset ; 00595 jcu_error = R_JCU_SetEncodeParam( &encode, &buffer ); 00596 if ( jcu_error != JCU_ERROR_OK ) { 00597 e = JPEG_CONV_PARAM_RANGE_ERR ; 00598 mutex_release = true; 00599 jcu_error_flag = true; 00600 goto fin; 00601 } 00602 if (pOptions->encode_buff_size > 0) { 00603 00604 while(BufferSize > ENC_SIZE_MAX) { 00605 size_max_count *= 2; 00606 BufferSize /= 2; 00607 } 00608 BufferSize = BufferSize & MASK_8BYTE; 00609 00610 count_para.inputBuffer.isEnable = false; 00611 count_para.inputBuffer.isInitAddress = false; 00612 count_para.inputBuffer.restartAddress = NULL; 00613 count_para.inputBuffer.dataCount = 0; 00614 count_para.outputBuffer.isEnable = true; 00615 count_para.outputBuffer.isInitAddress = false; 00616 count_para.outputBuffer.restartAddress = NULL; 00617 count_para.outputBuffer.dataCount = BufferSize; 00618 00619 R_JCU_SetCountMode(&count_para); 00620 } else { 00621 size_max_count = 0; 00622 } 00623 // Check async 00624 if ( pOptions->p_EncodeCallBackFunc == NULL ) { 00625 jcu_error = R_JCU_Start(); 00626 mutex_release = true; 00627 if ( jcu_error != JCU_ERROR_OK ) { 00628 e = JPEG_CONV_JCU_ERR ; 00629 jcu_error_flag = true; 00630 goto fin; 00631 } 00632 if (pOptions->encode_buff_size > 0) { 00633 // Check Pause flag 00634 R_JCU_GetAsyncStatus( &status ); 00635 for ( encode_count = 1; (encode_count < size_max_count) && (status->IsPaused != false); encode_count++) { 00636 if ((status->SubStatusFlags & JCU_SUB_ENCODE_OUTPUT_PAUSE) == 0) { 00637 e = JPEG_CONV_JCU_ERR ; 00638 jcu_error_flag = true; 00639 goto fin; 00640 } 00641 jcu_error = R_JCU_Continue( JCU_OUTPUT_BUFFER ); 00642 if (jcu_error != JCU_ERROR_OK) { 00643 e = JPEG_CONV_JCU_ERR ; 00644 jcu_error_flag = true; 00645 goto fin; 00646 } 00647 R_JCU_GetAsyncStatus( &status ); 00648 } 00649 if (status->IsPaused != false) { 00650 e = JPEG_CONV_PARAM_RANGE_ERR ; 00651 jcu_error_flag = true; 00652 goto fin; 00653 } 00654 } 00655 (void)R_JCU_GetEncodedSize(pEncodeSize); 00656 } else { 00657 pJPEG_ConverterCallback = pOptions->p_EncodeCallBackFunc ; 00658 jcu_error = R_wrpper_set_encode_callback((mbed_CallbackFunc_t*)JPEG_CallbackFunction, pEncodeSize, size_max_count); 00659 if ( jcu_error != JCU_ERROR_OK ) { 00660 e = JPEG_CONV_JCU_ERR ; 00661 goto fin; 00662 } 00663 } 00664 e = JPEG_CONV_OK ; 00665 } else { 00666 e = JPEG_CONV_PARAM_RANGE_ERR ; 00667 } 00668 fin: 00669 if (mutex_release == true) { 00670 jpeg_converter_semaphore.release(); // RELEASE 00671 } 00672 00673 return e; 00674 } /* End of method encode() */ 00675
Generated on Tue Jul 12 2022 11:15:01 by 1.7.2