c - SIGSEGV 同时将 1 位图像数据转换为 8 位

标签 c image-processing segmentation-fault

我将图像数据存储在 unsigned char 中大批。数据的形式为RGB0RGB0每个字节,即每个字节和每个RGB之后覆盖两个像素一个0被填充以便将其对齐 4 的倍数。为了进一步处理,我需要将每个颜色分量数据 1 位转换为每个分量 8 位,即每种颜色 1 个字节。所以我正在做的是,对于每个字节,我检查 MSB,如果它是 1 ,我设置一个字节为 0xFF否则我就留下它0 。我写的代码如下:

void
convert_pixels(unsigned char *pixdata,
               unsigned char *convertedpix,
               int width,
               int height)
{
    int i,j,k, count=0;
    unsigned int mask;
    unsigned char temp;
    for(i=0;i<height;i++)
    {
        count=0;
        for(j=0;j<width;j++)
        {
            temp = *(pixdata+i*width+j);
            for (mask = 0x80; mask != 0; mask >>= 1)
            {
                if ((temp & mask) && mask!=0x10 && mask!=0x01)
                    *(convertedpix+i*width*6+count)=0xFF;
                count++;
            }
        }
    }
}

它在执行时给出 SIGSEGV。 btgdb给出:

(gdb) bt
#0  0x00000000004014b0 in convert_pixels (pixdata=0x7f008a0cf010 '\377' <repeats 200 times>..., 
    pixdata@entry=0x7f00967e2010 'w' <repeats 200 times>..., convertedpix=0x7f00967e2010 'w' <repeats 200 times>..., 
    convertedpix@entry=0x7f008a0cf010 '\377' <repeats 200 times>..., width=width@entry=4958, height=height@entry=7017) at image_convert.c:166
#1  0x0000000000401007 in main (argc=<optimized out>, argv=<optimized out>) at image_convert.c:355

数组 convertedpix已分配的内存恰好是 6 pixdata 的倍:

if(header.cupsBitsPerColor==1)
        {
            convertedpix = (unsigned char*)calloc(header.cupsWidth * header.cupsHeight*6,
                                                                                        sizeof(unsigned char));
            convert_pixels(pixdata, convertedpix, header.cupsWidth,
                                         header.cupsHeight);
        }

最佳答案

您会遇到段错误,因为您以与内存布局不匹配的方式增加计数和宽度,最终会从分配的内存中写入数据。如果移动宽度和高度,则循环中的计数应相应地从 0 变为 5。

void
convert_pixels(unsigned char *pixdata, unsigned char *convertedpix,
               int width, int height) {
    int i, j, k;
    unsigned int mask;
    unsigned char temp;
    for(i = 0; i < height; ++i) {
        for(j = 0; j < width; ++j) {
            k = 0;
            temp = *(pixdata + i * width + j);
            for (mask = 0x80; mask != 0; mask >>= 1) {
                if (mask != 0x10 && mask != 0x01) { /* code below will be 
                                                     * executed 6 times */
                    if (temp & mask) { 
                        *(convertedpix + i * width + k) = 0xFF;
                    } else {
                        *(convertedpix + i * width + k) = 0;
                    }
                    ++k;
                }
            }
        }
    }
}

另外,请添加对calloc返回值的检查(可能是内存分配有问题):

if (header.cupsBitsPerColor==1) {
    convertedpix = (unsigned char*) calloc(header.cupsWidth *
                                  header.cupsHeight * 6, sizeof(unsigned char));
    if (convertedpix != NULL) {
        convert_pixels(pixdata, convertedpix, header.cupsWidth, 
                                                      header.cupsHeight);
    } else {
        /* handle error */
    }
}

Usage

关于c - SIGSEGV 同时将 1 位图像数据转换为 8 位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38126132/

相关文章:

c - 通过 TCP 发送的文件创建类型为 : application/octet-stream

c - 重用变量是好是坏?

python - 如何使用 python opencv 去除这些图片中的阴影?

c++ - segmentation 故障的常见原因的明确列表

c - 第二次 fgets 后出现段错误

c - 请帮助解释这个域正在做什么(使用函数在数组中添加斐波那契序列元素的程序)

c - SO_KEEPALIVE 和轮询

image - 如何在 Matlab 中傅立叶相位扰乱灰度 JPEG 图像?

algorithm - 无法在 MATLAB 中分隔标记

c++ - 树实现给出段错误(核心转储)错误 c++ 11