【问题标题】:SIGSEGV while converting 1 bit image data into 8 bitSIGSEGV 同时将 1 位图像数据转换为 8 位
【发布时间】:2016-06-30 14:28:08
【问题描述】:

我将图像数据存储在 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。 bt on 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 乘以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);
        }

【问题讨论】:

  • 你确定convertedpix指向的数组是pixdata指向的数组的6倍吗?
  • @LPs 是的,我已将内存分配给convertedpix,这正是6pixdata

标签: c image-processing segmentation-fault


【解决方案1】:

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

【讨论】:

  • 我试过了,但它也提供了 SIGSEGV。这不起作用,因为convetedpix 的宽度正好是6 乘以pixdata。您的解决方案没有考虑到这一点
  • @Pranjal 当然它不起作用,因为它是为 8 倍大的阵列而设计的。请检查更新的代码。
  • 你还有 SIGSEGV 吗?你能粘贴完整的例子吗?
  • @Pranjal 我想看看你如何分配数组并调用 convert_pixels
  • 我已经添加了。请看一下
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-13
  • 2014-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-17
相关资源
最近更新 更多