如何扭转这个功能

Iva*_*nov 0 c#

之前我曾经问过Bitwise AND(&)的反面,你告诉我它无法逆转.

嗯,情况就是这样:服务器发送一个图像,用我想要反转的函数编码,然后用zlib编码.

这是我从服务器获取图像的方式:

        UInt32[] image = new UInt32[200 * 64];
        int imgIndex = 0;
        byte[] imgdata = new byte[compressed];
        byte[] imgdataout = new byte[uncompressed];

        Array.Copy(data, 17, imgdata, 0, compressed);
        imgdataout = zlib.Decompress(imgdata);
        for (int h = 0; h < height; h++)
        {
            for (int w = 0; w < width; w++)
            {
                imgIndex = (int)((height - 1 - h) * width + w);
                image[imgIndex] = 0xFF000000;
                if (((1 << (Int32)(0xFF & (w & 0x80000007))) & imgdataout[((h * width + w) >> 3)]) > 0)
                {
                    image[imgIndex] = 0xFFFFFFFF;
                }
            }
        }
Run Code Online (Sandbox Code Playgroud)

宽度,高度,图像解压缩和图像压缩长度始终相同.

当这个功能完成后,我把图像(UInt32 []数组)放在一个位图中,我就知道了.

现在我想成为服务器并发送该图像.我必须做两件事:

反转该函数,然后使用zlib压缩它.

如何反转该功能以便对图片进行编码?

    for (int h = 0; h < height; h++)
    {
        for (int w = 0; w < width; w++)
        {
            imgIndex = (int)((height - 1 - h) * width + w);
            image[imgIndex] = 0xFF000000;
            if (((1 << (Int32)(0xFF & (w & 0x80000007))) & imgdataout[((h * width + w) >> 3)]) > 0)
            {
                image[imgIndex] = 0xFFFFFFFF;
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

编辑:格式为32bppRGB

Aln*_*tak 6

&操作员总是不可逆的假设是不正确的.

是的,一般情况下,如果你有

c = a & b
Run Code Online (Sandbox Code Playgroud)

和所有你知道的价值c,那么你可以不知道什么值ab前手了.

然而,&用于从较长值中提取某些位是非常常见的,其中这些位先前与|运算符组合在一起,并且每个"位字段"彼此独立.与通用&|运算符的基本区别使得这种可逆性是原始位预先全为零,并且字中的其他位保持不变.即:

0xc0 | 0x03 = 0xc3   // combine two nybbles

0xc3 & 0xf0 = 0xc0   // extract the top nybble
0xc3 & 0x0f = 0x03   // extract the bottom nybble
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您当前的功能似乎是提取每像素1位(单色图像)并将其转换为32位RGBA.

你需要这样的东西:

int source_image[];
byte dest_image[];

for (int h = 0; h < height; ++h) {
    for (int w = 0; w < width; ++w) {
        int offset = (h * width) + w;
        if (source_image[offset] == 0xffffffff) {
            int mask = w % 8; // these two lines convert from one int-per-pixel
            offset /= 8;      // offset to one-bit-per-pixel
            dest_image[offset] |= (1 << mask); // only changes _one_ bit
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:假设图像是8像素宽的倍数,该dest_image数组先前全为零.我已经使用%/在内部测试,因为它更容易理解和编译器应该转换为掩盖/移动本身.通常情况下,我会做掩蔽并改变自己.