View Full Version : Better way to do this
Ceppo
25th February 2016, 20:32
I want to make a block-based filter but i don't really get the way pixels are stored in avisynth's memory. Let's say that the picture is a multidimensional array where x is the width and y is the height, how do i do src[y=2][x=3] (the third pixel of the second line).
At the moment i'm doing a 4x4 block-based processing this way but is not much usable.
for( y = 0; y < height; y+=4 ) {
for( x = 0; x < width; x+=4 ) {
for( b = 0; b < 4; b++ ) {
for( a = 0; a < 4; a++ ) {
dstp[x+a] = 255;
}
srcp += src_pitch;
dstp += dst_pitch;
}
srcp -= (src_pitch*4);
dstp -= (dst_pitch*4);
}
srcp += (src_pitch*4);
dstp += (dst_pitch*4);
}
feisty2
25th February 2016, 20:58
src[y=2][x=3]
srcp[src_pitch*(2-1)+3-1]
feisty2
25th February 2016, 21:03
The pointer is uint8_t * not uint8_t ** so [][] kind of syntactic sugar stuff is not allowed
Ceppo
25th February 2016, 21:39
Thanks a lot for the help, I changed the code to this.
for( y = 0; y < height; y+=4 ) {
for( x = 0; x < width; x+=4 ) {
for( b = 0; b < 4; b++ ) {
for( a = 0; a < 4; a++ ) {
dstp[dst_pitch*(y+b)+(x+a)] = 255;
}
}
}
}
(I wanted to write [y=1][x=2] but i forgot that the count starts from 0 for a moment :p)
feisty2
25th February 2016, 22:05
Okay, this s**t is totally insane but pretty funny...
uint8_t **_2dptr = new uint8_t *[height];
for (int h=0; h<height; ++h)
_2dptr[h] = srcp + h * src_pitch;
Now you can use it like _2dptr[y=2][x=3] style...
Ceppo
27th February 2016, 17:26
I will stick with the first one, thanks anyway :D
StainlessS
28th February 2016, 06:32
Perhaps something like this would be ok (untested)
const int dst_pitch_x4 = dst_pitch*4
// const int src_pitch_x4 = src_pitch*4
for(int y = 0; y < height; y+=4 ) {
BYTE *dblkp = drcp; // 4*4 block Top:Left
// const BYTE *sblkp = srcp; //
for(int x = 0; x < width; x+=4) {
BYTE *dlinep = dblkp; // top row within 4*4 block
// const BYTE *slinep = sblkp;
for(int row = 0; row < 4; ++row ) {
// for(int col = 0; col < 4; ++col ) {
// dlinep[col] = 255;
// }
dlinep[0] = 255; // Do away with col for/next loop
dlinep[1] = 255;
dlinep[2] = 255;
dlinep[3] = 255;
//
dlinep += dst_pitch; // Next row in 4*4 block
// slinep += src_pitch; //
}
dblkp += 4; // Next 4*4 block (Top:Left)
// sblkp += 4; //
}
dstp += dst_pitch_x4; // or eg, drcp += dst_pitch * 4
// srcp += src_pitch_x4; //
}
oops, changed eg, slinep[0] = 255; to dlinep[0] = 255;
EDIT: Source ptrs etc not used above, but there anyway.
EDIT: Assumes y+3 < height and x+3 < width (as does your code).
EDIT: Additions only within loops (faster).
EDIT: Could also do away with row for/next loop by repeating contents of row loop 4 times.
ie replace
for(int row = 0; row < 4; ++row ) {
// for(int col = 0; col < 4; ++col ) {
// dlinep[col] = 255;
// }
dlinep[0] = 255; // Do away with col for/next loop
dlinep[1] = 255;
dlinep[2] = 255;
dlinep[3] = 255;
//
dlinep += dst_pitch; // Next row in 4*4 block
// slinep += src_pitch;
}
with (faster, no loop, removed final pitch additions)
dlinep[0] = 255; // Row 0
dlinep[1] = 255;
dlinep[2] = 255;
dlinep[3] = 255;
dlinep += dst_pitch;
// slinep += src_pitch;
//
dlinep[0] = 255; // Row 1
dlinep[1] = 255;
dlinep[2] = 255;
dlinep[3] = 255;
dlinep += dst_pitch;
// slinep += src_pitch;
//
dlinep[0] = 255; // Row 2
dlinep[1] = 255;
dlinep[2] = 255;
dlinep[3] = 255;
dlinep += dst_pitch;
// slinep += src_pitch;
//
dlinep[0] = 255; // Row 3
dlinep[1] = 255;
dlinep[2] = 255;
dlinep[3] = 255;
// dlinep += dst_pitch; // NOT NECESSARY
// slinep += src_pitch; //
Ceppo
2nd March 2016, 18:04
Thank you StainlessS but i like my code more (the shorter the better) :D
StainlessS
3rd March 2016, 02:15
Thank you StainlessS but i like my code more (the shorter the better) :D
It is so refreshing to find someone who is not obsessed with speed.
Your indentation style is quite horrible, glad I dont have to read a lot of it (another benefit of shorter code) :)
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.