- Main Page
- Modules
- Namespaces
- Classes
- Files

- Search for |

- File List
- File Members

# samples/common/classes/NvJpegDecoder.cpp

Go to the documentation of this file.

    00001 /*
    00002  * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
    00003  *
    00004  * Redistribution and use in source and binary forms, with or without
    00005  * modification, are permitted provided that the following conditions
    00006  * are met:
    00007  *  * Redistributions of source code must retain the above copyright
    00008  *    notice, this list of conditions and the following disclaimer.
    00009  *  * Redistributions in binary form must reproduce the above copyright
    00010  *    notice, this list of conditions and the following disclaimer in the
    00011  *    documentation and/or other materials provided with the distribution.
    00012  *  * Neither the name of NVIDIA CORPORATION nor the names of its
    00013  *    contributors may be used to endorse or promote products derived
    00014  *    from this software without specific prior written permission.
    00015  *
    00016  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
    00017  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    00018  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    00019  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
    00020  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    00021  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    00022  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    00023  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
    00024  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    00026  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    00027  */
    00028
    00029 #include "NvJpegDecoder.h"
    00030 #include "NvLogging.h"
    00031 #include <string.h>
    00032 #include <malloc.h>
    00033 #include "unistd.h"
    00034 #include "stdlib.h"
    00035
    00036 #define MAX(a, b) ((a) > (b) ? (a) : (b))
    00037 #define ROUND_UP_4(num)  (((num) + 3) & ~3)
    00038
    00039 #define CAT_NAME "JpegDecoder"
    00040
    00041 NvJPEGDecoder::NvJPEGDecoder(const char *comp_name)
    00042     :NvElement(comp_name, valid_fields)
    00043 {
    00044     memset(&cinfo, 0, sizeof(cinfo));
    00045     memset(&jerr, 0, sizeof(jerr));
    00046     cinfo.err = jpeg_std_error(&jerr);
    00047
    00048     jpeg_create_decompress(&cinfo);
    00049 }
    00050
    00051 NvJPEGDecoder *
    00052 NvJPEGDecoder::createJPEGDecoder(const char *comp_name)
    00053 {
    00054     NvJPEGDecoder *jpegdec = new NvJPEGDecoder(comp_name);
    00055     if (jpegdec->isInError())
    00056     {
    00057         delete jpegdec;
    00058         return NULL;
    00059     }
    00060     return jpegdec;
    00061 }
    00062
    00063 NvJPEGDecoder::~NvJPEGDecoder()
    00064 {
    00065     jpeg_destroy_decompress(&cinfo);
    00066     CAT_DEBUG_MSG(comp_name << " (" << this << ") destroyed");
    00067 }
    00068
    00069 int
    00070 NvJPEGDecoder::decodeToFd(int &fd, unsigned char * in_buf,
    00071         unsigned long in_buf_size, uint32_t &pixfmt, uint32_t &width,
    00072         uint32_t &height)
    00073 {
    00074     uint32_t pixel_format = 0;
    00075     uint32_t buffer_id;
    00076
    00077     if (in_buf == NULL || in_buf_size == 0)
    00078     {
    00079         COMP_ERROR_MSG("Not decoding because input buffer = NULL or size = 0");
    00080         return -1;
    00081     }
    00082
    00083     buffer_id = profiler.startProcessing();
    00084
    00085     cinfo.out_color_space = JCS_YCbCr;
    00086
    00087     jpeg_mem_src(&cinfo, in_buf, in_buf_size);
    00088
    00089     cinfo.out_color_space = JCS_YCbCr;
    00090
    00091     /* Read file header, set default decompression parameters */
    00092     (void) jpeg_read_header(&cinfo, TRUE);
    00093
    00094     cinfo.out_color_space = JCS_YCbCr;
    00095     cinfo.IsVendorbuf = TRUE;
    00096
    00097     if (cinfo.comp_info[0].h_samp_factor == 2)
    00098     {
    00099         if (cinfo.comp_info[0].v_samp_factor == 2)
    00100         {
    00101             pixel_format = V4L2_PIX_FMT_YUV420M;
    00102         }
    00103         else
    00104         {
    00105             pixel_format = V4L2_PIX_FMT_YUV422M;
    00106         }
    00107     }
    00108     else
    00109     {
    00110         if (cinfo.comp_info[0].v_samp_factor == 1)
    00111         {
    00112             pixel_format = V4L2_PIX_FMT_YUV444M;
    00113         }
    00114         else
    00115         {
    00116             pixel_format = V4L2_PIX_FMT_YUV422RM;
    00117         }
    00118     }
    00119
    00120     jpeg_start_decompress (&cinfo);
    00121     jpeg_read_raw_data (&cinfo, NULL, cinfo.comp_info[0].v_samp_factor * DCTSIZE);
    00122     jpeg_finish_decompress(&cinfo);
    00123
    00124     width = cinfo.image_width;
    00125     height = cinfo.image_height;
    00126     pixfmt = pixel_format;
    00127     fd = cinfo.fd;
    00128
    00129     COMP_DEBUG_MSG("Succesfully decoded Buffer fd=" << fd);
    00130
    00131     profiler.finishProcessing(buffer_id, false);
    00132     return 0;
    00133 }
    00134
    00135 int
    00136 NvJPEGDecoder::decodeToBuffer(NvBuffer ** buffer, unsigned char * in_buf,
    00137         unsigned long in_buf_size, uint32_t *pixfmt, uint32_t * width,
    00138         uint32_t * height)
    00139 {
    00140     unsigned char **line[3];
    00141     unsigned char *y[4 * DCTSIZE] = { NULL, };
    00142     unsigned char *u[4 * DCTSIZE] = { NULL, };
    00143     unsigned char *v[4 * DCTSIZE] = { NULL, };
    00144     int i, j;
    00145     int lines, v_samp[3];
    00146     unsigned char *base[3], *last[3];
    00147     int stride[3];
    00148     NvBuffer *out_buf = NULL;
    00149     uint32_t pixel_format = 0;
    00150     uint32_t buffer_id;
    00151
    00152     if (buffer == NULL)
    00153     {
    00154         COMP_ERROR_MSG("Not decoding because buffer = NULL");
    00155         return -1;
    00156     }
    00157
    00158     if (in_buf == NULL || in_buf_size == 0)
    00159     {
    00160         COMP_ERROR_MSG("Not decoding because input buffer = NULL or size = 0");
    00161         return -1;
    00162     }
    00163
    00164     buffer_id = profiler.startProcessing();
    00165
    00166     cinfo.out_color_space = JCS_YCbCr;
    00167     jpeg_mem_src(&cinfo, in_buf, in_buf_size);
    00168     cinfo.out_color_space = JCS_YCbCr;
    00169
    00170     (void) jpeg_read_header(&cinfo, TRUE);
    00171
    00172     cinfo.out_color_space = JCS_YCbCr;
    00173
    00174     if (cinfo.comp_info[0].h_samp_factor == 2)
    00175     {
    00176         if (cinfo.comp_info[0].v_samp_factor == 2)
    00177         {
    00178             pixel_format = V4L2_PIX_FMT_YUV420M;
    00179         }
    00180         else
    00181         {
    00182             pixel_format = V4L2_PIX_FMT_YUV422M;
    00183         }
    00184     }
    00185     else
    00186     {
    00187         if (cinfo.comp_info[0].v_samp_factor == 1)
    00188         {
    00189             pixel_format = V4L2_PIX_FMT_YUV444M;
    00190         }
    00191         else
    00192         {
    00193             pixel_format = V4L2_PIX_FMT_YUV422RM;
    00194         }
    00195     }
    00196
    00197     out_buf = new NvBuffer(pixel_format, cinfo.image_width,
    00198             cinfo.image_height, 0);
    00199     out_buf->allocateMemory();
    00200
    00201     jpeg_start_decompress (&cinfo);
    00202
    00203     line[0] = y;
    00204     line[1] = u;
    00205     line[2] = v;
    00206
    00207     for (i = 0; i < 3; i++)
    00208     {
    00209         v_samp[i] = cinfo.comp_info[i].v_samp_factor;
    00210         stride[i] = out_buf->planes[i].fmt.width;
    00211         base[i] = out_buf->planes[i].data;
    00212         last[i] = base[i] + (stride[i] * (out_buf->planes[i].fmt.height - 1));
    00213     }
    00214
    00215     for (i = 0; i < (int) cinfo.image_height; i += v_samp[0] * DCTSIZE)
    00216     {
    00217         for (j = 0; j < (v_samp[0] * DCTSIZE); ++j)
    00218         {
    00219             /* Y */
    00220             line[0][j] = base[0] + (i + j) * stride[0];
    00221
    00222             /* U,V */
    00223             if (pixel_format == V4L2_PIX_FMT_YUV420M)
    00224             {
    00225                 /* Y */
    00226                 line[0][j] = base[0] + (i + j) * stride[0];
    00227                 if ((line[0][j] > last[0]))
    00228                     line[0][j] = last[0];
    00229                 /* U */
    00230                 if (v_samp[1] == v_samp[0]) {
    00231                     line[1][j] = base[1] + ((i + j) / 2) * stride[1];
    00232                 } else if (j < (v_samp[1] * DCTSIZE)) {
    00233                     line[1][j] = base[1] + ((i / 2) + j) * stride[1];
    00234                 }
    00235                 if ((line[1][j] > last[1]))
    00236                     line[1][j] = last[1];
    00237                 /* V */
    00238                 if (v_samp[2] == v_samp[0]) {
    00239                     line[2][j] = base[2] + ((i + j) / 2) * stride[2];
    00240                 } else if (j < (v_samp[2] * DCTSIZE)) {
    00241                     line[2][j] = base[2] + ((i / 2) + j) * stride[2];
    00242                 }
    00243                 if ((line[2][j] > last[2]))
    00244                     line[2][j] = last[2];
    00245             }
    00246             else
    00247             {
    00248                 line[1][j] = base[1] + (i + j) * stride[1];
    00249                 line[2][j] = base[2] + (i + j) * stride[2];
    00250             }
    00251         }
    00252
    00253         lines = jpeg_read_raw_data (&cinfo, line, v_samp[0] * DCTSIZE);
    00254         if ((!lines))
    00255         {
    00256             COMP_DEBUG_MSG( "jpeg_read_raw_data() returned 0\n");
    00257         }
    00258     }
    00259
    00260     jpeg_finish_decompress(&cinfo);
    00261     if (width)
    00262     {
    00263         *width= cinfo.image_width;
    00264     }
    00265     if (height)
    00266     {
    00267         *height= cinfo.image_height;
    00268     }
    00269     if (pixfmt)
    00270     {
    00271         *pixfmt = pixel_format;
    00272     }
    00273     *buffer = out_buf;
    00274
    00275     COMP_DEBUG_MSG("Succesfully decoded Buffer " << buffer);
    00276
    00277     profiler.finishProcessing(buffer_id, false);
    00278
    00279     return 0;
    00280 }