Jpeg图像转yuv 16倍数问题(第二季)

  第一季中说到可能是jpeg_read_raw_data 中当图片的长度和宽度不是16的倍数会导致问题,这个问题对我来说要找到问题有点难度!

那能不能换个策略呢,在网上搜索看到不少的人用while (info_.output_scanline < info_.output_height)来控制读取数据,那应该可以尝试下:

基本思路是当图片的长度和宽度转换成4的倍数,采取多取像素原则(导致看到的图像边缘是红色或者别的颜色),基本上大多数尺寸的图片都可以读取。

在大量的测试过程中,发现个致命的问题:

  在释放 image_one[ci][bi]时会崩溃,经排除是jpeg_read_raw_data(&info_, image_one, (JDIMENSION)16) 导致数组越界,估计还是有的地方没有考虑到,

但是因为都这个库不熟悉又不知道怎么处理但好处是比以前的代码简洁易懂,可是不释放运行过久将导致内存崩溃。

  又是一个摆在眼前需要解决的问题? 不知道大家有没有碰到类似的问题。

  奉上代码

  (待续:第三季)

virtual int DecodeJpeg2YUV(unsigned char* pBuffer, int nSize)
    {
        //判断是否是jpge格式
        if (pBuffer[0] != 0xFF)
        {
            return IMAGLIB_FORMAT_ERR; //格式不对
        }
        jpeg_decompress_struct info_;  
        info_.err = jpeg_std_error(&e_);         
        jpeg_create_decompress(&info_); 
        jpeg_mem_src(&info_, pBuffer, nSize);   //// 指定图片在内存的地址及大小    

        // Get all compression parameters.
        jpeg_read_header(&info_, 1);     
        

        // Configure the decompressors for raw data output.
        info_.raw_data_out = TRUE;          
        jpeg_start_decompress(&info_);          

     
        int nPicHeight = 0;
        int nPicWidth  = 0;    


        //因为行的获取要4的倍数,可以修改值为4的倍数
        if (0 != info_.output_width % 4)
        {
             nPicWidth  = info_.output_width/16*16 + 16;
        }
        else
        {
            nPicWidth = info_.output_width; 
        }

        if (0 != info_.output_height % 4)
        {
            nPicHeight  = info_.output_height/16*16 + 16;
        }
        else
        {
            nPicHeight = info_.output_height; 
        }

        int nLen = nPicHeight * nPicWidth;
        m_nWidth = nPicWidth;
        m_nHeight = nPicHeight;
        NEW_BUFFER(m_pYbuffer, nLen);
        NEW_BUFFER(m_pUbuffer, nLen);
        NEW_BUFFER(m_pVbuffer, nLen);
    
        
        //分配内存获取数据
        int yx, yr,ci,bi;
        int yrowmcu = 0;
        JSAMPIMAGE image_one = (JSAMPIMAGE)malloc(3 * sizeof(JSAMPARRAY));    
        for (ci = 0; ci < 3; ci++)
        {
            image_one[ci] = (JSAMPARRAY)malloc(16 * sizeof(JSAMPROW));        
            for (bi = 0; bi < 16; bi++)
            {
                //image_one[ci][bi] = (JSAMPROW)malloc(info_.output_width * sizeof(JSAMPLE));
                image_one[ci][bi] = (JSAMPROW)malloc(m_nWidth * sizeof(JSAMPLE));
            }
        }        
    
        int nReadHeight = 0, yc = 0;
        int numfields = 1;
        while (info_.output_scanline < info_.output_height)
        {
            //读取数据
            jpeg_read_raw_data(&info_, image_one, (JDIMENSION)16);

            for (yr = 0; yr < 16; nReadHeight+=numfields, yr++)        
            {
                int xd =  nReadHeight*nPicWidth;
                //防止超过长度读取。
                if ((nReadHeight) >= info_.output_height)
                {
                    continue;
                }
                 for (yx = 0; yx < info_.output_width; yx++)
                 {
                     m_pYbuffer[xd++] = image_one[0][yr][yx];
                 }                
            }        
    
            
             for (yr = 0; yr < 8;  yr++, yc += numfields)
             {
                if (yc >= info_.output_height/2)
                {
                    continue;
                }
                int xd = yc * nPicWidth / 2;
                 for (yx = 0; yx < info_.output_width / 2; yx++, xd++)
                 {
                    m_pUbuffer[xd] = image_one[1][yr][yx];
                    m_pVbuffer[xd] = image_one[2][yr][yx];
                 }
             }
        }

        for (ci = 0; ci < 3; ci++)
        {
             for (bi = 0; bi < 16; bi++)
             {
                 free(image_one[ci][bi]);
             }            
            free(image_one[ci]);            
        }
        free(image_one);
        jpeg_finish_decompress(&info_); 
        jpeg_destroy_decompress(&info_); 
        return 0;
    
    }

 

转载于:https://www.cnblogs.com/ugly927846/archive/2013/06/08/3127226.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值