【问题标题】:Fetching n bytes from memory从内存中获取 n 个字节
【发布时间】:2011-11-17 11:22:18
【问题描述】:

假设我有一个指向图像数据的指针,它有 3 个通道 (RGB),每个通道 8 位,我想显示像 #000000 这样的像素值,它是一个 24 位数字。数据的存储方式类似于 RGB RGB RGB ... 所以我真的需要读取前三个字节。

typedef unsigned char uchar;
uchar* data = get_image_data_somehow();

也许它比我想象的要容易,但如果我有四个字节,我可以做类似的事情

uint32 value = *((uint32*) data);
printf("Value is %x", value);

这要怎么做?原则上我需要 32 位的 1,并用 0 填充前 8 位。

【问题讨论】:

    标签: c


    【解决方案1】:

    您可以右移 8 位来实现这一点。

    uint32_t value = *((uint32_t*) data) >> 8;
    printf("Value is %0X", value);
    

    data 是两个像素值#1177ff 的示例:

    data       = 11 77 ff 11 77 ff
    value      = 11 77 ff 11
    value >> 8 = 00 11 77 ff
    

    【讨论】:

    • %0X 会更好看。 +1 了。
    • @AdamZalcman:只是一个例子,并阐明数据类型的大小。例如,GLib 提供了相应的 typedef,如 guint32,我认为仅使用普通的“int”可能因机器而异。
    • @AdamZalcman - 在 OP 的代码中有。我假设他在某处得到了类型定义。如果您不喜欢uint32,请随意替换uint32_tunsigned int,尽管您碰巧可用的任何32 位无符号整数类型都可以完成这项工作。
    • @AdamZalcman - 是的,忘了那个。我在想int 是固定的,因为整个int/long int/long long 交易。我将更新原始代码以使用uint32_t
    • 嗯,这种方法似乎很合理,但不知何故……获取第一个字节(无符号字符)返回“0x2A”,这是我所期望的。但是用您建议的内容(没有移位)获取前四个字节会返回“0x2727262A”,这是我所期望的镜像,第一个 0x27 是第二个像素的红色值。这是否与小端等有关?移位后返回 0x27(而不是预期的 0x2A2627)
    【解决方案2】:
    memcpy( &value, data, 3 );
    value &= 0x00FFFFFF;
    

    (假设您使用的是 Little-Endian 机器)

    【讨论】:

    • LE 怎么样?正如作者所说,有一个严格的字节顺序。
    • 如果源(3 个字节)和目标(4 个字节)的大小不同,那么 memcpy 会对齐右侧的三个字节吗?
    • @AndrejsCainikovs 是的,没什么。 @wal-o-mat 对; target 中其他字节的内容是不变的(所以如果是未知的,清除它会更安全)。此外,memcpy 不会读取超出必要的内存,而复制 uint32 将读取 4 字节。不过,您的情况无需担心。
    【解决方案3】:

    您可以使用 union 来提取数据,或对其进行部门化。

    它看起来像这样:

    union myRGB {
        unsigned int data;
        struct RGB
        {
           unsigned char a, b, g, r;
        }
    }
    
    myRGB value = *((uint32*) data);
    
    printf("R Value is %x", value.RGB.a);
    

    RGB parsing example

    【讨论】:

    • 我也会在这里设置+1,但我认为你的代码写得不好并且有错误。
    • @AndrejsCainikovs 可能有错误,只是为概念起草的,您能指出错误吗?
    • 好吧,我已经解决了一些问题。我在这里考虑字节序,虽然这并不是真正的错误,但它可能不适用于某些架构。检查多项式答案下的 cmets。
    猜你喜欢
    • 2013-02-21
    • 1970-01-01
    • 1970-01-01
    • 2015-07-13
    • 2020-06-12
    • 2017-05-09
    • 2021-04-27
    • 2015-05-07
    • 1970-01-01
    相关资源
    最近更新 更多