第一季中说到可能是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; }