SIGSEGV将1位图像数据转换为8位

时间:2016-06-30 14:28:09

标签: c image-processing segmentation-fault

我将图像数据存储在unsigned char数组中。数据的格式为每字节RGB0RGB0,即每个字节覆盖两个像素,并在每个RGB之后填充0,以便将其与{4的倍数对齐1}}。为了进一步处理,我需要将每个颜色分量数据的这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。 bt上的gdb给出了:

(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的{​​{1}}倍:

pixdata

1 个答案:

答案 0 :(得分:2)

您会遇到分段错误,因为您以不与内存布局匹配的方式递增计数和宽度,并最终写出已分配的内存。如果你移动宽度和高度,那么count应该在循环中从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