Thread: Increment gone wrong

  1. #121
    Registered User
    Join Date
    Sep 2020
    Posts
    425
    Here's 37 lines that does those 200 lines correctly. Note how everything is handled identically.

    Code:
    static const int32_t  lut_code[19]         = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,-1, 0,  0};
    static const uint32_t lut_base_repeats[19] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 11};
    static const uint32_t lut_extra_bits[19]   = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3,  7};
    
    
    static int read_in_symbol_lengths(struct Inflate_data *d, struct Huff_node *code_tree,
                                      struct Codetable_entry *table, size_t table_len) {
       uint32_t current_code = 0, i = 0;
    
    
       for(i = 0; i < table_len; i++)
          table[i].length = 0;
    
    
       i = 0;
       while(i < table_len) {
          uint32_t t = grab_bits(d);
          uint32_t s = symbol_decode(code_tree,t);
          consume_bits(d,s>>24);
          s &=0xFF;
          int32_t  new_code   = lut_code[s];
          uint32_t repeat     = lut_base_repeats[s];
          uint32_t extra_bits = lut_extra_bits[s];
          uint32_t mask       = (1<<extra_bits)-1;
    
    
          if(new_code != -1)
             current_code = new_code;
    
    
          if(extra_bits > 0) {
             repeat += grab_bits(d) & mask;
             consume_bits(d,extra_bits);
          }
    
    
          while(repeat > 0 && i <= table_len) {
            table[i].length = current_code;
            i++; repeat--;
          }
       }
       return 1;
    }

  2. #122
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    1st I'll start with quoting those loop UIDs you gave but in order of UID so I can quickly find and compare my current ones

    Code:
    Distance table
       10:  1 0
       14:  3 100
       16:  3 101
       13:  4 1100
        0:  5 11010
        9:  5 11011
       12:  5 11100
       15:  5 11101
       17:  5 11110
       18:  5 11111
    Quote Originally Posted by hamster_nz View Post
    Here's 37 lines that does those 200 lines correctly. Note how everything is handled identically.

    Code:
    static const int32_t  lut_code[19]         = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,-1, 0,  0};
    static const uint32_t lut_base_repeats[19] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 11};
    static const uint32_t lut_extra_bits[19]   = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3,  7};
    
    
    static int read_in_symbol_lengths(struct Inflate_data *d, struct Huff_node *code_tree,
                                      struct Codetable_entry *table, size_t table_len) {
       uint32_t current_code = 0, i = 0;
    
    
       for(i = 0; i < table_len; i++)
          table[i].length = 0;
    
    
       i = 0;
       while(i < table_len) {
          uint32_t t = grab_bits(d);
          uint32_t s = symbol_decode(code_tree,t);
          consume_bits(d,s>>24);
          s &=0xFF;
          int32_t  new_code   = lut_code[s];
          uint32_t repeat     = lut_base_repeats[s];
          uint32_t extra_bits = lut_extra_bits[s];
          uint32_t mask       = (1<<extra_bits)-1;
    
    
          if(new_code != -1)
             current_code = new_code;
    
    
          if(extra_bits > 0) {
             repeat += grab_bits(d) & mask;
             consume_bits(d,extra_bits);
          }
    
    
          while(repeat > 0 && i <= table_len) {
            table[i].length = current_code;
            i++; repeat--;
          }
       }
       return 1;
    }
    Tried condensing to one loop as you suggested but this was the smallest I could get with current setup:
    Code:
    	while ( done < total )
    	{
    		while ( done < count && Stream->err == 0 )
    		{
    			int i = 0;
    			ZLIB_SYMBOL *Type = SeekZlibSymbol( Stream, Types );
    
    			memset( &Temp, 0, sizeof(ZLIB_FULL_SYMBOL) );
    
    			ZlibFullSymbol( &fullType, Type );
    			Temp.cpy = fullType.cpy;
    
    			if ( Type->lit < 16 )
    				Temp.len = loose ? Type->len + 1 : Type->lit;
    			else
    			{
    				Temp.cpy += StreamBits( Stream, fullType.get, true );
    				Temp.len = (Type->lit == 16) ? prv : codes->len;
    
    				if ( !Temp.len )
    				{
    					lit += Temp.cpy;
    					pos += Temp.cpy;
    					done += Temp.cpy;
    					Temp.cpy = 0;
    				}
    			}
    
    			Temp.use = !!(Temp.len);
    			prv = Temp.len;
    
    			if ( Temp.len > Codes->longest )
    				Codes->longest = Temp.len;
    
    			for ( i = 0; i < Temp.cpy; ++i, ++lit, ++pos, ++done )
    			{
    				Code = codes + pos;
    
    				Code->use = Temp.use;
    				Code->len = Temp.len;
    				Code->lit = lit;
    				Code->src = done - loose;
    			}
    		}
    
    		lit = ZLIB_LOOP_LIT0;
    		pos = ZLIB_MAX_TYPES + ZLIB_MAX_CODES;
    		count = total;
    		loose = keep;
    	}
    The problem of overly long loop UIDs still exist though

    No longer need a bunch of the pront statments that were being used, (c8384c61) * Commits * Lee Shallis / glEngine * GitLab

  3. #123
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Finally got it right! Don't remember where I read it but something made me think the loop codes were supposed to have the same length as the type code + 1, strange thing is that despite having tried using the same value I'm using now in previous versions of the code it never worked then, maybe the simplification of the code caused me to fix something unknowingly, anyways here's the upload:

    FINALLY! Image actuually came out correct with my own decompression (05ebc4c7) * Commits * Lee Shallis / glEngine * GitLab

  4. #124
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    With the zlib decompression fixed I'm moving onto fixing my filters as apparantly only filter type 0 was working correctly, before I proceed though I'd like to know if anyone has any ideas on how to re-arrange the below so that I don't need "pixel % Image->Cols" for filters 1, 3 & 4

    Code:
    #define ImagePixelX( IMAGE, PIXEL ) (((IMAGE)->Cols * 2) + PIXEL)
    /* Adds any offset/s for local pixel indices, index 0 is used for nil, do NOT
     * fill that index */
    #define ImagePixelA( IMAGE, PIXEL ) (ImagePixelX(IMAGE,PIXEL) - 1)
    #define ImagePixelB( IMAGE, PIXEL ) (ImagePixelX(IMAGE,PIXEL) - (IMAGE)->Cols)
    #define ImagePixelC( IMAGE, PIXEL ) (ImagePixelB(IMAGE,PIXEL) - 1)
    The buffer is made using
    Code:
    	view = ExpandBuffer
    	(
    		View,
    		sizeof(ulong),
    		ImagePixelX(Image,Image->Pixels) * IMAGE_CHANNEL_COUNT
    	);

  5. #125
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Never mind about the pixel grabbing, chose to go with a solution that required multiplying rows against columns

    Filter types 0 - 3 all work properly now, 4 resembles the expected (8b9c389d) * Commits * Lee Shallis / glEngine * GitLab

    Filter type 4 resembles the image (pngsuite/f04n0g08.png) but has corruption, not quite sure what I did wrong so I'll leave a dump of the PaethPreditctor function here, maybe someone will spot what I did wrong

    Code:
    ulong ImageFilterPaethPredictor( IMAGE *Image, ulong a, ulong b, ulong c )
    {
    	ulong depth = Image->Depth;
    	ulong keep = ~(~0 << depth);
    	ulong p = (((a + b) & keep) - c) & keep;
    	ulong pa = (p - a) & keep;
    	ulong pb = (p - b) & keep;
    	ulong pc = (p - c) & keep;
    
    	if ( pa <= pb && pa <= pc )
    		return a;
    
    	if ( pb <= pc )
    		return b;
    
    	return c;
    }
    Merged the above function into the only function that uses it, makes it a little easier to see what is being passed to it:

    Code:
    ulong ImageFilter4( IMAGE *Image, ulong channel, ulong row, ulong col )
    {
    	ulong a = ImageFilter1( Image, channel, row, col );
    	ulong b = ImageFilter2( Image, channel, row, col );
    	ulong c = ImageFilter3( Image, channel, row, col );
    	ulong p = (((a + b)) - c);
    	ulong pa = (p - a);
    	ulong pb = (p - b);
    	ulong pc = (p - c);
    
    	if ( pa <= pb && pa <= pc )
    		return a;
    
    	if ( pb <= pc )
    		return b;
    
    	return c;
    }

  6. #126
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Took me long enough to notice it but I figured out where I was going wrong for filter type 4, I was loading the wrong value as pixel c, fixing that resulted in the expected greyscale image, didn't check the last 2 yet but I will do that when I start managing to display them as textures (finally getting back to the main reason I started this).

    Figured out where I was going wrong (ee8972bf) * Commits * Lee Shallis / glEngine * GitLab

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. hex increment
    By davidx in forum C Programming
    Replies: 3
    Last Post: 10-19-2019, 07:06 AM
  2. Two pre increment in one expression
    By h255874 in forum C Programming
    Replies: 4
    Last Post: 09-21-2019, 08:47 AM
  3. Post Increment an Pre Increment operators in c++
    By anil_ in forum C++ Programming
    Replies: 4
    Last Post: 11-12-2011, 08:27 PM
  4. can't get loop to increment
    By rivkyfried1 in forum C Programming
    Replies: 2
    Last Post: 10-11-2010, 04:03 AM
  5. Post increment and pre increment help
    By noob2c in forum C++ Programming
    Replies: 5
    Last Post: 08-05-2003, 03:03 AM

Tags for this Thread