我有这个结构,它代表一个像素,它的三个8位块R,G,B :
typedef struct pixel_st {
uint8_t r, g, b;
} pixel_t;
pixel_t *array_of_pixels; // array of pixels
问题是,给定一个具有大量像素的数组,在循环中遍历 R、G 和 B 并删除它们的最后一位的最有效方法是什么,这些循环遍历文件及其字符的位。
问题可能不清楚,所以在代码中这基本上是我想做的:
For each character in file {
For each bit in character (its 7 last bits) {
change next color r, g or b of current pixel,
if all colors of pixel have been changed
go to next pixel
}
}
这是我尝试过的:
// iterators
char ch; // text file characters
pixel_t *pixel_iterator = array_of_pixels; // image pixels
uint8_t *r, *g, *b, i; // pixel colors
char last = ' ';
while((ch = getc(f)) != EOF) { // iterate through characters
for(i = 0; i < 7; i++) { // character size in ASCII
if(last == 'b' || last == ' ') { // first iteration, or last was b => go to r
if(last == 'b') { // go to next pixel
pixel_iterator++;
}
r = pixel_iterator->r >> 1;
r << 1;
last = 'r';
} else if(last == 'r') { // go to g
g = pixel_iterator->r >> 1;
g << 1;
last = 'g';
} else if(last == 'g') { // go to b
b = pixel_iterator->r >> 1;
b << 1;
last = 'b';
}
}
}
这看起来一点效率都没有。如果可能的话,我想用几行来做。
我正在解决您问题中的两点 - 迭代速度和您所说的"删除最后一点"的地方。
第一点 - 看看"工会"。 联合允许您覆盖结构,但将其视为不同的内存布局。 在您的特定情况下,您可以将 3x8 位值视为单个 24 位值。
然后,您一次读取 3 个字节。
当您开始将事物视为单个 24 位值时,很容易删除"最后一个"位......一些伪代码:
char[3] bytes = {}
long v = bytes[0]<<16 | bytes[1] << 8 | bytes[2]
long out = v & 0b111111101111111011111110
bytes[0] = out >> 16
bytes[1] = out >> 8
bytes[2] = out
注意 - 这是伪代码---请不要对语法进行批评:)
@paul - 我希望这有帮助!