Thread: de-filtering a 4 bit depth png image

  1. #1
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733

    de-filtering a 4 bit depth png image

    Been doing a work trial (which fell through because it was too much for my body to take) and left the code alone due to exhaustion, when I came back to it I had some bugs to fix (among which a memory management bug that only reveals itself when I try to launch opengl code paths), the one that is still difficult for me to understand is how to extract the correct information for de-filtering with, if anyone's inclined to help then could you look at RenderImagePNG() in png.c - did some re-organisation too for those who were familiar with the old crappier names I used - and ImageFilter*() in image.c

    Temporarily added official zlib library usage, this is to ensure the (488df536) * Commits * Lee Shallis / glEngine * GitLab

    The test image is f99n0g04 from here:

    PngSuite - Image filtering / PNG-files

    All the other test images from the same page produce the correct result because they use 8 bit values and my system uses an 8 bit 'char' so I know that the filter math is correct, only the depth handling that is incorrect

  2. #2
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    In addition to the failing bit depth handling during the de-filtering process I've noticed an (unrelated) issue with my zlib code (results are the same regardless of whether I use my code or official library), take a look at the output and see if you can spot what I'm on about:

    Code:
    make eog ARGS="--test-png --image-lod=2 --zlib-lod=2 -f ./assets/pngsuite/f00n0g08.png"
    ...
    ./a.out --test-png --image-lod=2 --zlib-lod=2 -f ./assets/pngsuite/f00n0g08.png && eog pic.ppm
    main.c:166: GProcessArgv( 6, 0x7ffc014c25c8 )
    main.c:59: TryAppArg(  -1,   1, 0x7ffc014c25c8 ) arg = './a.out', val = '(null)'
    main.c:59: TryAppArg(   1,   0, 0x7ffc014c25c8 ) arg = '--test-png', val = '(null)'
    main.c:59: TryAppArg(   2,   0, 0x7ffc014c25c8 ) arg = '--image-lod=2', val = '(null)'
    main.c:59: TryAppArg(   3,   0, 0x7ffc014c25c8 ) arg = '--zlib-lod=2', val = '(null)'
    main.c:59: TryAppArg(   4,   1, 0x7ffc014c25c8 ) arg = '-f', val = './assets/pngsuite/f00n0g08.png'
    visual/image/png.c:278: image_lod = 2
    visual/image/png.c:350: chunks[ 0]           13 56112528 'IHDR'
    visual/image/png.c:350: chunks[ 1]          262 50A6CEB6 'IDAT'
    visual/image/png.c:315: chunks[ 2]            0 00000000 'IEND'
    visual/image/png.c:367: Checking IHDR chunk is 1st...
    visual/image/png.c:381: Found! Extracting information...
    visual/image/png.c:402: Decompressing IDAT chunks...
    common/zlib.c:959: Zlib: method = 8, info = 7, type = 0, dictionary = false, check = 13
    common/zlib.c:853: last = 1, type = 10, IStream->used = 19
    common/zlib.c:726: Type Symbols List Details: foresee:  18, longest =  7, highest = 127, have =     256, used =     128
    type_symbols[         0]: _tt = false, src =   5, lit =   7, use =  true, get =  0, cpy =     1, len =  2, uid = 00
    type_symbols[         1]: _tt = false, src =   4, lit =   8, use =  true, get =  0, cpy =     1, len =  2, uid = 01
    type_symbols[         2]: _tt = false, src =   1, lit =  17, use =  true, get =  3, cpy =     3, len =  2, uid = 10
    type_symbols[         6]: _tt = false, src =   3, lit =   0, use =  true, get =  0, cpy =     1, len =  3, uid = 110
    type_symbols[        28]: _tt = false, src =  11, lit =   4, use =  true, get =  0, cpy =     1, len =  5, uid = 11100
    type_symbols[        29]: _tt = false, src =   9, lit =   5, use =  true, get =  0, cpy =     1, len =  5, uid = 11101
    type_symbols[        30]: _tt = false, src =   7, lit =   6, use =  true, get =  0, cpy =     1, len =  5, uid = 11110
    type_symbols[       124]: _tt = false, src =  17, lit =   1, use =  true, get =  0, cpy =     1, len =  7, uid = 1111100
    type_symbols[       125]: _tt = false, src =  15, lit =   2, use =  true, get =  0, cpy =     1, len =  7, uid = 1111101
    type_symbols[       126]: _tt = false, src =  13, lit =   3, use =  true, get =  0, cpy =     1, len =  7, uid = 1111110
    type_symbols[       127]: _tt = false, src =   0, lit =  16, use =  true, get =  2, cpy =     3, len =  7, uid = 1111111
    common/zlib.c:746: IStream Details: End Of Data =  true, End Of IStream = false, data = 0x7ffc00eb80b0, byte = 262, took = 588, used = 588
    Code Symbols List Details: foresee: 273, longest =  8, highest = 255, have =   65536, used =     256
    type_symbols[         0]: _tt = false, src =   0, lit =   0, use =  true, get =  0, cpy =     0, len =  2, uid =       00
    code_symbols[         4]: _tt = false, src = 264, lit = 264, use =  true, get =  0, cpy =    10, len =  4, uid =     0100
    code_symbols[         5]: _tt = false, src = 265, lit = 265, use =  true, get =  1, cpy =    11, len =  4, uid =     0101
    code_symbols[         6]: _tt = false, src = 272, lit = 272, use =  true, get =  2, cpy =    31, len =  4, uid =     0110
    code_symbols[        14]: _tt = false, src = 257, lit = 257, use =  true, get =  0, cpy =     3, len =  5, uid =    01110
    code_symbols[        15]: _tt = false, src = 258, lit = 258, use =  true, get =  0, cpy =     4, len =  5, uid =    01111
    code_symbols[        16]: _tt = false, src = 259, lit = 259, use =  true, get =  0, cpy =     5, len =  5, uid =    10000
    code_symbols[        17]: _tt = false, src = 260, lit = 260, use =  true, get =  0, cpy =     6, len =  5, uid =    10001
    code_symbols[        18]: _tt = false, src = 266, lit = 266, use =  true, get =  1, cpy =    13, len =  5, uid =    10010
    code_symbols[        38]: _tt = false, src =  58, lit =  58, use =  true, get =  0, cpy = 32593, len =  6, uid =   100110
    code_symbols[        39]: _tt = false, src =  63, lit =  63, use =  true, get = -624760512, cpy = -626053632, len =  6, uid =   100111
    code_symbols[        40]: _tt = false, src =  69, lit =  69, use =  true, get = 76464230, cpy = 76464486, len =  6, uid =   101000
    code_symbols[        41]: _tt = false, src = 254, lit = 254, use =  true, get =  0, cpy =     0, len =  6, uid =   101001
    code_symbols[        42]: _tt = false, src = 268, lit = 268, use =  true, get =  1, cpy =    17, len =  6, uid =   101010
    code_symbols[        86]: _tt = false, src =   2, lit =   2, use =  true, get =  0, cpy =     0, len =  7, uid =  1010110
    code_symbols[        87]: _tt = false, src =   3, lit =   3, use =  true, get = 24, cpy =     0, len =  7, uid =  1010111
    code_symbols[        88]: _tt = false, src =   6, lit =   6, use =  true, get =  0, cpy =     0, len =  7, uid =  1011000
    code_symbols[        89]: _tt = false, src =   8, lit =   8, use =  true, get =  0, cpy =     0, len =  7, uid =  1011001
    code_symbols[        90]: _tt = false, src =  13, lit =  13, use =  true, get = 1879048191, cpy =     0, len =  7, uid =  1011010
    code_symbols[        91]: _tt = false, src =  25, lit =  25, use =  true, get =  0, cpy = 105872, len =  7, uid =  1011011
    code_symbols[        92]: _tt = false, src =  29, lit =  29, use =  true, get =  0, cpy = -620705760, len =  7, uid =  1011100
    code_symbols[        93]: _tt = false, src =  33, lit =  33, use =  true, get =  0, cpy = 76464198, len =  7, uid =  1011101
    code_symbols[        94]: _tt = false, src =  42, lit =  42, use =  true, get =  0, cpy = 21873, len =  7, uid =  1011110
    code_symbols[        95]: _tt = false, src =  52, lit =  52, use =  true, get =  0, cpy = 21873, len =  7, uid =  1011111
    code_symbols[        96]: _tt = false, src =  82, lit =  82, use =  true, get = 32593, cpy = 21873, len =  7, uid =  1100000
    code_symbols[        97]: _tt = false, src = 103, lit = 103, use =  true, get = 76464502, cpy = 76464758, len =  7, uid =  1100001
    code_symbols[        98]: _tt = false, src = 111, lit = 111, use =  true, get = 76464566, cpy = -624788752, len =  7, uid =  1100010
    code_symbols[        99]: _tt = false, src = 118, lit = 118, use =  true, get = 21873, cpy = 32593, len =  7, uid =  1100011
    code_symbols[       100]: _tt = false, src = 135, lit = 135, use =  true, get = 76464758, cpy = 76465014, len =  7, uid =  1100100
    code_symbols[       101]: _tt = false, src = 142, lit = 142, use =  true, get = 32593, cpy = 32593, len =  7, uid =  1100101
    code_symbols[       102]: _tt = false, src = 150, lit = 150, use =  true, get = 32593, cpy = 21873, len =  7, uid =  1100110
    code_symbols[       103]: _tt = false, src = 164, lit = 164, use =  true, get = 32593, cpy =     0, len =  7, uid =  1100111
    code_symbols[       104]: _tt = false, src = 184, lit = 184, use =  true, get = 21873, cpy =     0, len =  7, uid =  1101000
    code_symbols[       105]: _tt = false, src = 190, lit = 190, use =  true, get = 32764, cpy =     0, len =  7, uid =  1101001
    code_symbols[       106]: _tt = false, src = 196, lit = 196, use =  true, get =  0, cpy =     1, len =  7, uid =  1101010
    code_symbols[       107]: _tt = false, src = 238, lit = 238, use =  true, get =  1, cpy =     2, len =  7, uid =  1101011
    code_symbols[       108]: _tt = false, src = 248, lit = 248, use =  true, get =  0, cpy =     4, len =  7, uid =  1101100
    code_symbols[       109]: _tt = false, src = 250, lit = 250, use =  true, get =  0, cpy =     5, len =  7, uid =  1101101
    code_symbols[       110]: _tt = false, src = 251, lit = 251, use =  true, get =  0, cpy =     5, len =  7, uid =  1101110
    code_symbols[       111]: _tt = false, src = 253, lit = 253, use =  true, get =  0, cpy =     0, len =  7, uid =  1101111
    code_symbols[       224]: _tt = false, src =   1, lit =   1, use =  true, get =  9, cpy =     0, len =  8, uid = 11100000
    code_symbols[       225]: _tt = false, src =   4, lit =   4, use =  true, get =  0, cpy =     0, len =  8, uid = 11100001
    code_symbols[       226]: _tt = false, src =  10, lit =  10, use =  true, get =  0, cpy =     0, len =  8, uid = 11100010
    code_symbols[       227]: _tt = false, src =  15, lit =  15, use =  true, get =  1, cpy = -626054576, len =  8, uid = 11100011
    code_symbols[       228]: _tt = false, src =  19, lit =  19, use =  true, get = 76457898, cpy =     0, len =  8, uid = 11100100
    code_symbols[       229]: _tt = false, src =  22, lit =  22, use =  true, get =  0, cpy = 32593, len =  8, uid = 11100101
    code_symbols[       230]: _tt = false, src =  38, lit =  38, use =  true, get =  0, cpy = 21873, len =  8, uid = 11100110
    code_symbols[       231]: _tt = false, src =  47, lit =  47, use =  true, get = -626054576, cpy = 76464310, len =  8, uid = 11100111
    code_symbols[       232]: _tt = false, src =  76, lit =  76, use =  true, get = 21873, cpy = 21873, len =  8, uid = 11101000
    code_symbols[       233]: _tt = false, src =  89, lit =  89, use =  true, get = -625646816, cpy = -624761696, len =  8, uid = 11101001
    code_symbols[       234]: _tt = false, src =  96, lit =  96, use =  true, get = 32593, cpy = 21873, len =  8, uid = 11101010
    code_symbols[       235]: _tt = false, src = 127, lit = 127, use =  true, get = 76464694, cpy = -625735232, len =  8, uid = 11101011
    code_symbols[       236]: _tt = false, src = 157, lit = 157, use =  true, get = 76464934, cpy = 21772166, len =  8, uid = 11101100
    code_symbols[       237]: _tt = false, src = 171, lit = 171, use =  true, get = 76465046, cpy =     0, len =  8, uid = 11101101
    code_symbols[       238]: _tt = false, src = 178, lit = 178, use =  true, get = 21873, cpy =     3, len =  8, uid = 11101110
    code_symbols[       239]: _tt = false, src = 201, lit = 201, use =  true, get =  0, cpy =     1, len =  8, uid = 11101111
    code_symbols[       240]: _tt = false, src = 206, lit = 206, use =  true, get =  0, cpy =     1, len =  8, uid = 11110000
    code_symbols[       241]: _tt = false, src = 211, lit = 211, use =  true, get =  7, cpy =    11, len =  8, uid = 11110001
    code_symbols[       242]: _tt = false, src = 216, lit = 216, use =  true, get =  0, cpy =     0, len =  8, uid = 11110010
    code_symbols[       243]: _tt = false, src = 220, lit = 220, use =  true, get =  0, cpy =     0, len =  8, uid = 11110011
    code_symbols[       244]: _tt = false, src = 225, lit = 225, use =  true, get =  1, cpy =     0, len =  8, uid = 11110100
    code_symbols[       245]: _tt = false, src = 228, lit = 228, use =  true, get =  1, cpy =     0, len =  8, uid = 11110101
    code_symbols[       246]: _tt = false, src = 232, lit = 232, use =  true, get =  1, cpy =     0, len =  8, uid = 11110110
    code_symbols[       247]: _tt = false, src = 235, lit = 235, use =  true, get =  1, cpy =     1, len =  8, uid = 11110111
    code_symbols[       248]: _tt = false, src = 241, lit = 241, use =  true, get =  3, cpy =     3, len =  8, uid = 11111000
    code_symbols[       249]: _tt = false, src = 244, lit = 244, use =  true, get =  0, cpy =     3, len =  8, uid = 11111001
    code_symbols[       250]: _tt = false, src = 246, lit = 246, use =  true, get =  0, cpy =     4, len =  8, uid = 11111010
    code_symbols[       251]: _tt = false, src = 252, lit = 252, use =  true, get =  0, cpy =     5, len =  8, uid = 11111011
    code_symbols[       252]: _tt = false, src = 255, lit = 255, use =  true, get =  0, cpy =     0, len =  8, uid = 11111100
    code_symbols[       253]: _tt = false, src = 256, lit = 256, use =  true, get =  0, cpy =     0, len =  8, uid = 11111101
    code_symbols[       254]: _tt = false, src = 261, lit = 261, use =  true, get =  0, cpy =     7, len =  8, uid = 11111110
    code_symbols[       255]: _tt = false, src = 267, lit = 267, use =  true, get =  1, cpy =    15, len =  8, uid = 11111111
    Loop Symbols List Details: foresee:  19, longest =  8, highest = 31, have =  131072, used =     256
    code_symbols[         0]: _tt = false, src =  10, lit = 298, use =  true, get =  4, cpy =    33, len =  1, uid =        0
    loop_symbols[         4]: _tt = false, src =  14, lit = 302, use =  true, get =  6, cpy =   129, len =  3, uid =      100
    loop_symbols[         5]: _tt = false, src =  16, lit = 304, use =  true, get =  7, cpy =   257, len =  3, uid =      101
    loop_symbols[        12]: _tt = false, src =  13, lit = 301, use =  true, get =  5, cpy =    97, len =  4, uid =     1100
    loop_symbols[        26]: _tt = false, src =   0, lit = 288, use =  true, get =  0, cpy =     1, len =  5, uid =    11010
    loop_symbols[        27]: _tt = false, src =   9, lit = 297, use =  true, get =  3, cpy =    25, len =  5, uid =    11011
    loop_symbols[        28]: _tt = false, src =  12, lit = 300, use =  true, get =  5, cpy =    65, len =  5, uid =    11100
    loop_symbols[        29]: _tt = false, src =  15, lit = 303, use =  true, get =  6, cpy =   193, len =  5, uid =    11101
    loop_symbols[        30]: _tt = false, src =  17, lit = 305, use =  true, get =  7, cpy =   385, len =  5, uid =    11110
    loop_symbols[        31]: _tt = false, src =  18, lit = 306, use =  true, get =  8, cpy =   513, len =  5, uid =    11111
    common/zlib.c:987: Zlib: method = 8, info = 7, type = 0, dictionary = false, check = 13, expected = 000003F7, actual = CF2F0849
    visual/image/png.c:432: Processing gAMA chunk if it exists...
    visual/image/png.c:455: Attempting to render to given block...
    visual/image/png.c:511: Rendering png image, bitsof(uchar) vs bitsof(uch) = 8 vs 8 ...
      0 [   7F   87   8E   96   9D   A4   AB   B2   B8   BE   C4   C9   CE   D3   D8   DC   E1   E4   E8   EB   EE   F1   F4   F6   F8   FA   FB   FC   FD   FE   FE   FF ]
      0 [   76   7F   87   8E   96   9D   A4   AB   B2   B8   BE   C4   C9   CE   D3   D8   DC   E1   E4   E8   EB   EE   F1   F4   F6   F8   FA   FB   FC   FD   FE   FE ]
      0 [   6F   76   7F   87   8E   96   9D   A4   AB   B2   B8   BE   C4   C9   CE   D3   D8   DC   E1   E4   E8   EB   EE   F1   F4   F6   F8   FA   FB   FC   FD   FE ]
      0 [   67   6F   76   7F   87   8E   96   9D   A4   AB   B2   B8   BE   C4   C9   CE   D3   D8   DC   E1   E4   E8   EB   EE   F1   F4   F6   F8   FA   FB   FC   FD ]
      0 [   60   67   6F   76   7F   87   8E   96   9D   A4   AB   B2   B8   BE   C4   C9   CE   D3   D8   DC   E1   E4   E8   EB   EE   F1   F4   F6   F8   FA   FB   FC ]
      0 [   59   60   67   6F   76   7F   87   8E   96   9D   A4   AB   B2   B8   BE   C4   C9   CE   D3   D8   DC   E1   E4   E8   EB   EE   F1   F4   F6   F8   FA   FB ]
      0 [   52   59   60   67   6F   76   7F   87   8E   96   9D   A4   AB   B2   B8   BE   C4   C9   CE   D3   D8   DC   E1   E4   E8   EB   EE   F1   F4   F6   F8   FA ]
      0 [   4C   52   59   60   67   6F   76   7F   87   8E   96   9D   A4   AB   B2   B8   BE   C4   C9   CE   D3   D8   DC   E1   E4   E8   EB   EE   F1   F4   F6   F8 ]
      0 [   45   4C   52   59   60   67   6F   76   7F   87   8E   96   9D    0    0    0    0    0    0   C9   CE   D3   D8   DC   E1   E4   E8   EB   EE   F1   F4   F6 ]
      0 [   3F   45   4C   52   59   60   67   6F   76   7F   87   8E    0    0    0    0    0    0    0    0   C9   CE   D3   D8   DC   E1   E4   E8   EB   EE   F1   F4 ]
      0 [   3A   3F   45   4C   52   59   60   67   6F   76   7F    0    0    0   9D   A4   AB   B2    0    0    0   C9   CE   D3   D8   DC   E1   E4   E8   EB   EE   F1 ]
      0 [   34   3A   3F   45   4C   52   59   60   67   6F   76    0    0   8E   96   9D   A4   AB   B2    0    0   C4   C9   CE   D3   D8   DC   E1   E4   E8   EB   EE ]
      0 [   2F   34   3A   3F   45   4C   52   59   60   67   6F    0    0   87   8E   96   9D   A4    0    0    0   BE   C4   C9   CE   D3   D8   DC   E1   E4   E8   EB ]
      0 [   2A   2F   34   3A   3F   45   4C   52   59   60   67    0    0   7F   87   8E   96    0    0    0    0   B8   BE   C4   C9   CE   D3   D8   DC   E1   E4   E8 ]
      0 [   26   2A   2F   34   3A   3F   45   4C   52   59   60    0    0   76   7F   87    0    0    0    0    0   B2   B8   BE   C4   C9   CE   D3   D8   DC   E1   E4 ]
      0 [   21   26   2A   2F   34   3A   3F   45   4C   52   59    0    0   6F   76    0    0    0   96    0    0   AB   B2   B8   BE   C4   C9   CE   D3   D8   DC   E1 ]
      0 [   1D   21   26   2A   2F   34   3A   3F   45   4C   52    0    0   67    0    0    0   87   8E    0    0   A4   AB   B2   B8   BE   C4   C9   CE   D3   D8   DC ]
      0 [   19   1D   21   26   2A   2F   34   3A   3F   45   4C    0    0    0    0    0   76   7F   87    0    0   9D   A4   AB   B2   B8   BE   C4   C9   CE   D3   D8 ]
      0 [   16   19   1D   21   26   2A   2F   34   3A   3F   45    0    0    0    0   67   6F   76   7F    0    0   96   9D   A4   AB   B2   B8   BE   C4   C9   CE   D3 ]
      0 [   13   16   19   1D   21   26   2A   2F   34   3A   3F    0    0    0   59   60   67   6F   76    0    0   8E   96   9D   A4   AB   B2   B8   BE   C4   C9   CE ]
      0 [    F   13   16   19   1D   21   26   2A   2F   34   3A    0    0   4C   52   59   60   67   6F    0    0   87   8E   96   9D   A4   AB   B2   B8   BE   C4   C9 ]
      0 [    D    F   13   16   19   1D   21   26   2A   2F   34    0    0    0   4C   52   59   60    0    0    0   7F   87   8E   96   9D   A4   AB   B2   B8   BE   C4 ]
      0 [    A    D    F   13   16   19   1D   21   26   2A   2F   34    0    0    0    0    0    0    0    0   6F   76   7F   87   8E   96   9D   A4   AB   B2   B8   BE ]
      0 [    8    A    D    F   13   16   19   1D   21   26   2A   2F   34    0    0    0    0    0    0   60   67   6F   76   7F   87   8E   96   9D   A4   AB   B2   B8 ]
      0 [    6    8    A    D    F   13   16   19   1D   21   26   2A   2F   34   3A   3F   45   4C   52   59   60   67   6F   76   7F   87   8E   96   9D   A4   AB   B2 ]
      0 [    4    6    8    A    D    F   13   16   19   1D   21   26   2A   2F   34   3A   3F   45   4C   52   59   60   67   6F   76   7F   87   8E   96   9D   A4   AB ]
      0 [    3    4    6    8    A    D    F   13   16   19   1D   21   26   2A   2F   34   3A   3F   45   4C   52   59   60   67   6F   76   7F   87   8E   96   9D   A4 ]
      0 [    2    3    4    6    8    A    D    F   13   16   19   1D   21   26   2A   2F   34   3A   3F   45   4C   52   59   60   67   6F   76   7F   87   8E   96   9D ]
      0 [    1    2    3    4    6    8    A    D    F   13   16   19   1D   21   26   2A   2F   34   3A   3F   45   4C   52   59   60   67   6F   76   7F   87   8E   96 ]
      0 [    0    1    2    3    4    6    8    A    D    F   13   16   19   1D   21   26   2A   2F   34   3A   3F   45   4C   52   59   60   67   6F   76   7F   87   8E ]
      0 [    0    0    1    2    3    4    6    8    A    D    F   13   16   19   1D   21   26   2A   2F   34   3A   3F   45   4C   52   59   60   67   6F   76   7F   87 ]
      0 [    0    0    0    1    2    3    4    6    8    A    D    F   13   16   19   1D   21   26   2A   2F   34   3A   3F   45   4C   52   59   60   67   6F   76   7F ]
    Image Details: Cols =    32, Rows =    32, Depth =  8, sBIT = 00000000, Pixels =       1024
    Bytes = 1, Expect = 1280, Given = 1056, Given * Bytes = 1056, sBITr = 00000000, sBITg = 00000000, sBITb = 00000000, Flags = 0x00000000
    Compression Method = 0x00000000, Filter Method = 0x00000000, Interlace Method = 0x00000000, Max Colours 0
    Compilation finished successfully.
    Not currently a priority to look into this but for anyone inclined to do so before I eventually come back to it start with FullZlibSymbol() in zlib.c
    Lee Shallis / glEngine * GitLab

  3. #3
    Registered User
    Join Date
    Sep 2020
    Posts
    425
    Code:
    expected = 000003F7, actual = CF2F0849
    

    ?

  4. #4
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Quote Originally Posted by hamster_nz View Post
    Code:
    expected = 000003F7, actual = CF2F0849
    

    ?
    Oh that's just the unsupported CRC part that I'll get to later, for now it's just a place holder

  5. #5
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Having found a way to compare the values of the original vs the result I found there appears to be a problem with my 'nearest' filter

    (Bottom function, rest are provided for context)
    Code:
    long ImageFilterReturn0( IMAGE *Image, int ViewID, IMAGE_CHANNELS channel, ulong row, ulong col, long keep )
    {
    	(void)row;
    	(void)col;
    	(void)keep;
    	(void)Image;
    	(void)ViewID;
    	(void)channel;
    	return 0;
    }
    
    long ImageFilterRetrunA( IMAGE *Image, int ViewID, IMAGE_CHANNELS channel, ulong row, ulong col, long keep )
    {
    	(void)keep;
    	return *ImagePixel( Image, ViewID, channel, ImagePixelA( Image, row, col ) );
    }
    
    long ImageFilterReturnB( IMAGE *Image, int ViewID, IMAGE_CHANNELS channel, ulong row, ulong col, long keep )
    {
    	(void)keep;
    	return *ImagePixel( Image, ViewID, channel, ImagePixelB( Image, row, col ) );
    }
    
    long ImageFilterAverage( IMAGE *Image, int ViewID, IMAGE_CHANNELS channel, ulong row, ulong col, long keep )
    {
    	long a = *ImagePixel( Image, ViewID, channel, ImagePixelA( Image, row, col ) );
    	long b = *ImagePixel( Image, ViewID, channel, ImagePixelB( Image, row, col ) );
    	return ((a + b) / 2);// & keep;
    }
    
    long ForcePositive( long value )
    {
    	return (value < 0) ? -value : value;
    }
    
    long ImageFilterClosest( IMAGE *Image, int ViewID, IMAGE_CHANNELS channel, ulong row, ulong col, long keep )
    {
    	long a = *ImagePixel( Image, ViewID, channel, ImagePixelA( Image, row, col ) );
    	long b = *ImagePixel( Image, ViewID, channel, ImagePixelB( Image, row, col ) );
    	long c = *ImagePixel( Image, ViewID, channel, ImagePixelC( Image, row, col ) );
    	long p = (a + b - c);// & keep;
    	long pa = ForcePositive(p - a);// & keep;
    	long pb = ForcePositive(p - b);// & keep;
    	long pc = ForcePositive(p - c);// & keep;
    
    	if ( pa <= pb && pa <= pc )
    		return a;
    
    	if ( pb <= pc )
    		return b;
    
    	return c;
    }
    The reason I believe so is because the 2nd pixel that should have a colour is not as bright as expecting,, the odd thing is that the filter works on the test samples - f04n0g08.png & f04n2c08.png, PngSuite - Image filtering / PNG-files

  6. #6
    Registered User
    Join Date
    Sep 2020
    Posts
    425
    Here's my equivalent:

    Code:
                int32_t a=0,b=0,c=0;
                if(x > bytes_per_pixel) {
                   a = img->scanline[y]->data[x-bytes_per_pixel];
                }
                if(y > 0) {
                   b = img->scanline[y-1]->data[x];
                   if(x > bytes_per_pixel) {
                      c = img->scanline[y-1]->data[x-bytes_per_pixel];
                   }
                }
                int32_t p = a + b - c;
                int32_t pa = (a > p ? a-p : p-a);
                int32_t pb = (b > p ? b-p : p-b);
                int32_t pc = (c > p ? c-p : p-c);
                if(pa <= pb && pa <= pc) {
                   predicted = a;
                } else if (pb <= pc) {
                   predicted = b;
                } else {
                   predicted = c;
                }

  7. #7
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Quote Originally Posted by hamster_nz View Post
    Here's my equivalent:

    Code:
                int32_t a=0,b=0,c=0;
                if(x > bytes_per_pixel) {
                   a = img->scanline[y]->data[x-bytes_per_pixel];
                }
                if(y > 0) {
                   b = img->scanline[y-1]->data[x];
                   if(x > bytes_per_pixel) {
                      c = img->scanline[y-1]->data[x-bytes_per_pixel];
                   }
                }
                int32_t p = a + b - c;
                int32_t pa = (a > p ? a-p : p-a);
                int32_t pb = (b > p ? b-p : p-b);
                int32_t pc = (c > p ? c-p : p-c);
                if(pa <= pb && pa <= pc) {
                   predicted = a;
                } else if (pb <= pc) {
                   predicted = b;
                } else {
                   predicted = c;
                }
    Well for starters I'm actually working with 2 buffers, both contain the final result but the 1st buffer contains an extra column and row to remove the conditionals from the process, the extra column and row always contain 0 so A, B, & C pixels can always have the correct value without checking the position. Secondly what's the point of assigning the return value to an internal variable? Just return directly and then you can skip the "else" part of the conditionals, anyways my problem wasn't the logic but getting the overflow/underflow to happen in the right places since that is where the root of my problem lies, My code only worked so far because the overflow/underflow it was causing happened to align with 8 bit depth which I was working with, I need a way to cause it regardless of bit depth which is not so easy. I have one last idea to try then I'm completely wrung dry. For reference here's what my filters currently look like (not sure if I uploaded it yesterday):

    Code:
    float ImageFilterReturn0( IMAGE_FILTER *ImageFilter )
    {
    	(void)ImageFilter;
    	return 0.0;
    }
    
    float ImageFilterReturnA( IMAGE_FILTER *ImageFilter )
    {
    	return ImageFilter->A->raw[ImageFilter->Value];
    }
    
    float ImageFilterReturnB( IMAGE_FILTER *ImageFilter )
    {
    	return ImageFilter->B->raw[ImageFilter->Value];
    }
    
    float ImageFilterReturnC( IMAGE_FILTER *ImageFilter )
    {
    	return ImageFilter->C->raw[ImageFilter->Value];
    }
    
    float ImageFilterReturnD( IMAGE_FILTER *ImageFilter )
    {
    	return ImageFilter->D->raw[ImageFilter->Value];
    }
    
    float ImageFilterAverage( IMAGE_FILTER *ImageFilter )
    {
    	float a = ImageFilterReturnA( ImageFilter );
    	float b = ImageFilterReturnB( ImageFilter );
    	return ((a + b) / 2);
    }
    
    float ImageFilterClosest( IMAGE_FILTER *ImageFilter )
    {
    	float a = ImageFilterReturnA( ImageFilter );
    	float b = ImageFilterReturnB( ImageFilter );
    	float c = ImageFilterReturnC( ImageFilter );
    	float p = (a + b) - c;
    	float pa = fabsf(p - a);
    	float pb = fabsf(p - b);
    	float pc = fabsf(p - c);
    
    	if ( pa <= pb && pa <= pc )
    		return a;
    
    	if ( pb <= pc )
    		return b;
    
    	return c;
    }
    And here's what I've been referencing for the PaethFilter (which for the sake of same length names I re-named to "Closest"):

    Portable Network Graphics (PNG) Specification (Second Edition)

  8. #8
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Well integer math was definitely the way to go, the filters do appear to work for 8 bit values and I can remove the forced underflow/overflow code by just shifting the values to the end in the intermediate buffer, still have issues with the last filter test though (the one with 4bit depth) so I'm not sure what is expected there.

    Integer math is definitly the way to go for image filters apparently, (2f4a40b0) * Commits * Lee Shallis / glEngine * GitLab

  9. #9
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Finally figured out the root of my problem, it was never the filters, it was the way I was reading the expanded zlib data (after zlib or my version had been through it), still haven't managed to fix it but the resulting top row of pixels (ignoring the uppermost black bar which is supposed to be black) now looks much closer to how it should

    Found the root of the problem with the 4bit results (737245bb) * Commits * Lee Shallis / glEngine * GitLab

    Portable Network Graphics (PNG) Specification (Second Edition)
    In PNG images of colour type 0 (greyscale) each pixel is a single sample, which may have precision less than a byte (1, 2, or 4 bits). These samples are packed into bytes with the leftmost sample in the high-order bits of a byte followed by the other samples for the scanline.

    My IStreamData() function works from the bottom of the values when I should be working from the top, since I haven't though of a way to resolve this without conditionals I've chosen to forgo that and switch to a manual function:

    Code:
    ulong HiddenImageIStreamPNG( uch **tok, c16 *bit, uint take, bool rim_check )
    {
    	ulong top = 1u << (bitsof(uch) - 1);
    	ulong val = 0;
    	ulong num;
    
    	for ( num = 0; num < take; ++num )
    	{
    		val <<= 1;
    		val |= !!((**tok) & *bit);
    
    		*bit >>= 1;
    
    		if ( !(*bit) )
    		{
    			 ++(*tok);
    			 *bit = top;
    		}
    	}
    
    	if ( rim_check && *bit < top )
    	{
    		++(*tok);
    		*bit = top;
    	}
    
    	return val;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. filtering
    By kezkez in forum C Programming
    Replies: 3
    Last Post: 07-05-2010, 05:13 PM
  2. Filtering the return key
    By SilentPirate007 in forum C Programming
    Replies: 1
    Last Post: 03-09-2010, 04:41 PM
  3. Need Help Filtering just the first letter
    By Sshakey6791 in forum C++ Programming
    Replies: 2
    Last Post: 12-23-2008, 03:16 PM
  4. Filtering a string?
    By Look- in forum C# Programming
    Replies: 1
    Last Post: 04-18-2008, 07:41 AM
  5. C++ in Depth or Java In Depth... ?
    By jawwadalam in forum C++ Programming
    Replies: 8
    Last Post: 10-07-2002, 08:38 AM

Tags for this Thread