Last active
June 8, 2023 09:44
-
-
Save heatblazer/0d726a4c64c48bb1384e22f0d4a753ec to your computer and use it in GitHub Desktop.
zigzaging of NxN matrix
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
/** | |
* | |
*Entropy coding is a special form of lossless data compression. | |
*It involves arranging the image components in a "zigzag" order employing run-length encoding (RLE) algorithm that groups similar frequencies together, inserting length coding zeros, and then using Huffman coding on what is left. | |
The JPEG standard also allows, but does not require, decoders to support the use of arithmetic coding, which is mathematically superior to Huffman coding. | |
However, this feature has rarely been used, as it was historically covered by patents requiring royalty-bearing licenses, and because it is slower to encode and decode compared to Huffman coding. | |
Arithmetic coding typically makes files about 5–7% smaller. | |
The previous quantized DC coefficient is used to predict the current quantized DC coefficient. The difference between the two is encoded rather than the actual value. The encoding of the 63 quantized AC coefficients does not use such prediction differencing. | |
as given | |
[1][2][3][4] | |
[5][6][7][8] | |
[9][1][2][3] | |
[4][5][6][7] | |
shall output: | |
[1][2][5][9] | |
[6][3][4][7] | |
[1][4][5][2] | |
[8][3][6][7] | |
*/ | |
//define debug with size for the local array for debugging | |
//#define DBG 64 | |
//helper get an element at x,y | |
int getat(const int* mat, const int x, const int y, const int rows) | |
{ | |
return mat[y * rows + x]; | |
} | |
#if DBG >= 4 | |
void zigzag(const int* mat, const int ROWS, const int COLS,...) | |
#else | |
void zigzag(const int* mat, const int ROWS, const int COLS,int* outmat) | |
#endif | |
{ | |
//bitmasking the location and mask for diagonals to bitwise compare | |
// if you go down for example, | |
// then after that you mask a diagonal walk to be as (FORWARD | UP) | |
//and reversed respectively | |
enum Location { | |
UP = 0x1, | |
DOWN = 0x2, | |
FORWARD = 0x4, | |
BACKWARD = 0x8 | |
}; | |
int i=0,j=0,h=0; | |
int location = FORWARD; | |
int diag = 0; //helper calc of diag i - j or j - i | |
#ifdef DBG | |
int outmat[DBG] = {0}; | |
#endif | |
if (!mat || !outmat) return; | |
//if not a regular matrix - do nothing - can't zigzag | |
if (ROWS != COLS || ROWS==0 || COLS==0) | |
{ | |
return; | |
} | |
//loop till x and y does not equal end of matrix | |
// eg 3x3 to be i == 2 and j == 2 | |
while(i != ROWS-1 || j != ROWS-1) | |
{ | |
if (location == (BACKWARD | DOWN)) { | |
diag = i-j; | |
for(int d =0 ; d < diag; d++) | |
outmat[h++] = getat(mat, --i, ++j, ROWS); | |
if (j < COLS-1) | |
location = DOWN; | |
else | |
location = FORWARD; | |
} | |
if (location == (FORWARD | UP)) { | |
diag = j-i; | |
for(int d=0; d < diag; d++) | |
outmat[h++] = getat(mat, ++i, --j, ROWS); | |
if (i+1 >= ROWS) | |
location = DOWN; | |
else | |
location = FORWARD; | |
} | |
if (location == DOWN) { | |
outmat[h++] = getat(mat, i, ++j, ROWS); | |
if (i < ROWS-1) | |
location = (FORWARD | UP); | |
else | |
location = (BACKWARD | DOWN); | |
} | |
if (location == FORWARD) { | |
//this is the end case scenario | |
// at the end even if i > j by one and are not equall, | |
// the while loop will stop after the increment after the | |
// if (i==0 && j==0) since we will get | |
// getat(mat, ++i, j) and they become equall | |
if (i==0 && j==0) | |
outmat[h++] = getat(mat, i, j, ROWS); | |
outmat[h++] = getat(mat, ++i, j, ROWS); | |
if (i <= ROWS-1 && j ==0) | |
location = (BACKWARD | DOWN); | |
else | |
location = (FORWARD | UP); | |
} | |
} | |
#ifdef DBG | |
for(int i=0; i < ROWS * COLS; i++) { | |
std::cout << "{" << outmat[i] << "}"; | |
} | |
std::cout << "\r\n"; | |
#endif | |
} | |
// driver test programs ---------------------------------------------// | |
void drivertest2x2() | |
{ | |
const int mat2x2[] = { | |
1,2, //0 | |
3,4 //1 | |
}; | |
int newmat2x2[4] = {0}; | |
zigzag(mat2x2, 2,2, newmat2x2); | |
for(int i=0; i < 4; i++) { | |
if (i % 2 == 0) std::cout << "\r\n"; | |
std::cout << "[" << newmat2x2[i] << "]"; | |
} | |
std::cout << "\r\n---------\r\n"; | |
} | |
void drivertest3x3() | |
{ | |
const int mat3x3[] = { | |
1,2,3, //0 | |
4,5,6, //1 | |
7,8,9 //2 | |
}; | |
int newmat3x3[9] = {0}; | |
zigzag(mat3x3, 3,3, newmat3x3); | |
for(int i=0; i < 9; i++) { | |
if (i %3 == 0) std::cout << "\r\n"; | |
std::cout << "[" << newmat3x3[i] << "]"; | |
} | |
std::cout << "\r\n---------\r\n"; | |
} | |
void drivertest4x4() | |
{ | |
const int mat4x4[] = { | |
1,2,3,4, //0 | |
5,6,7,8, //1 | |
9,1,2,3, //2 | |
4,5,6,7 //3 | |
}; | |
int newmat4x4[16] = {0}; | |
zigzag(mat4x4, 4,4, newmat4x4); | |
for(int i=0; i < 16; i++) { | |
if (i % 4 == 0) std::cout << "\r\n"; | |
std::cout << "[" << newmat4x4[i] << "]"; | |
} | |
std::cout << "\r\n---------\r\n"; | |
} | |
void drivertest8x8() | |
{ | |
const int mat8x8[] = { | |
1,2,3,4,5,6,7,8, //0 | |
0,0,0,0,0,0,0,0, //1 | |
0,0,0,0,0,0,0,0, //2 | |
0,0,0,0,0,0,0,0, //3 | |
0,0,0,0,0,0,0,0, //4 | |
0,0,0,0,0,0,0,0, //5 | |
0,0,0,0,0,6,6,6, //6 | |
0,0,0,0,0,10,11,12 //7 | |
}; | |
int newmat8x8[64] = {0}; | |
zigzag(mat8x8, 8,8, newmat8x8); | |
for(int i=0; i < 64; i++) { | |
if (i % 8 == 0) std::cout << "\r\n"; | |
std::cout << "[" << newmat8x8[i] << "]"; | |
} | |
std::cout << "\r\n----------\r\n"; | |
} | |
int main(int argc, char** argv) | |
{ | |
(void)argc; (void)argv; | |
std::cout << "Begin\r\n"; | |
drivertest2x2(); | |
drivertest3x3(); | |
drivertest4x4(); | |
drivertest8x8(); | |
std::cout << "finish\r\n"; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment