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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers JPEG_Coverter.cpp Source File

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