Quote Originally Posted by hamster_nz View Post
With a seed of zero, after a while it gets stuck in a loop of repeating 35,246 values.

If you are feeling idle, try this:

Code:
static uint32_t my_rng(unsigned int x) {
   unsigned int b;
   b = x ^ (x << 3);
   b = ((~b) >> 16) & 0x7FFF;
   x = (x << 15) | b;
   return x;
}
It generates 2,147,483,647 unique values...
If I'm able to put it under an MIT License then sure, otherwise I'll stick to searching for another method, the main reason I was looking for a method was so I can add it to my alu project, anyways I decided libpng was too complicated for my liking, I wanted a library that allows me to ........ up the file itself and just tells me what I can do with my buffer to make it compliant, so I've gone with writing my own functions, here's what I got so far:
Code:
int print_png_sig( FILE *out )
{
	char sig[8] = { 137, 80, 78, 71, 13, 10, 26, 10 };
	size_t bytes = fwrite( sig, 1, 8, out );
	return (bytes != 8) ? ferror(out) : 0;
}

void flip_bytes( void *buff, size_t size )
{
	for ( char *a = buff, *b = buff + (size-1); a < b; ++a, --b )
	{
		char t = *a;
		*a = *b;
		*b = t;
	}
}

void* flip_words( void *buff, size_t size )
{
	for ( short *a = buff, *b = buff + (size-2); a < b; ++a, --b )
	{
		short t = *a;
		*a = *b;
		*b = t;
	}
	
	return buff;
}

void* set_little_endian( void *buff, size_t size )
{
	long val = 0x12345678;
	char *ptr = (char*)&val;
	bool go = true;
	
	while ( 1 )
	{
		switch ( *ptr )
		{
		case 0x78: return buff;
		case 0x12: flip_bytes( buff, size ); return buff;
		case 0x34:
			flip_words( buff, size );
		case 0x56:
			for ( size_t i = 0; i < size; i += 2 )
			{
				flip_bytes( ptr + i, 2 );
			}
			return buff;
		}
	
		if ( !go ) return buff;
		
		flip_bytes( buff, size );
		go = false;
	}
	
	return buff;
}

struct png_IHDR
{
	size_t length : 32;
	size_t type : 32;
	size_t crc : 32;
	size_t width : 32;
	size_t height : 32;
	size_t bit_depth : 8;
	size_t color_type : 8;
	size_t comparison_method : 8;
	size_t filter_method : 8;
	size_t interlace_method : 8;
};

#define PNG_COLOR_TYPE_GREYSCALE 0
#define PNG_COLOR_TYPE_TRUECOLOR 2
#define PNG_COLOR_TYPE_INDEXED 3
#define PNG_COLOR_TYPE_GREYSCALE_WITH_ALPHA 4
#define PNG_COLOR_TYPE_TRUECOLOR_WITH_ALPHA 6

#define PNG_COMPRESSION_SLIDING_WINDOW_OF_AT_MOST_0x7fff 0

#define PNG_FILTER_ADAPTIVE_WITH_5_TYPES 0

#define PNG_INTERLACE_NONE 0
#define PNG_INTERLACE_ADAM7 1

size_t set_png_IHDR_color_type( struct *png_IHDR chunk, size_t color_type )
{
	switch ( color_type )
	{
	case PNG_COLOR_TYPE_GREYSCALE:
	case PNG_COLOR_TYPE_TRUECOLOR:
	case PNG_COLOR_TYPE_INDEXED:
	case PNG_COLOR_TYPE_GREYSCALE_WITH_ALPHA:
	case PNG_COLOR_TYPE_TRUECOLOR_WITH_ALPHA:
		break;
	default:
		color_type = PNG_COLOR_TYPE_TRUECOLOR_WITH_ALPHA;
	}
	
	chunk->color_type = color_type;
	return color_type;
}

size_t set_png_IHDR_bit_depth
(
	struct *png_IHDR chunk
	, size_t color_type
	, size_t bit_depth
)
{
	switch ( bit_depth )
	{
		case 3:
			bit_depth = 4;
		case 1: case 2: case 4:
			bit_depth =
			(
				color_type == PNG_COLOR_TYPE_GREYSCALE
				|| color_type == PNG_COLOR_TYPE_INDEXED
			) ? bit_depth : 8;
			break;
		case 6: case 7:
			bit_depth = 8;
		case 8: break;
		default:
			bit_depth = (color_type != PNG_COLOR_TYPE_INDEXED) ? 16 : 8;
	}
	
	chunk->bit_depth = bit_depth;
	return bit_depth;
}

int print_png_chunk_IHDR( FILE *out, struct png_IHDR *chunk )
{
	// Ignored CRC
	int ret = 1;
	char type[4] = { 73, 72, 68, 82 };
	size_t leng = sizeof(png_IHDR) - 4, crc = 0;
	size_t bytes;
	
	struct { size_t size, void *addr } ptrs[] =
	{
		{ 4, &(chunk->leng) }
		, { 4, memcpy( &(chunk->type), type, 4 ) }
		, { 4, &(chunk->crc) }
		, { 0, NULL }
	};
	
	set_little_endian( &leng, 4 );
	(void)memcpy( &(chunk->leng), &leng, 4 )
	
	for ( int i = 0; ptrs[i].addr; ++i )
	{
		bytes = fwrite( ptrs[i], 1, ptrs[i].size, out );
		
		if ( bytes != ptrs[i].size )
			return ferror(out);
	}
	
	return ret;
}
Anyone see any problems?