/* double_ppm_brightness.c - Don Yang (uguu.org) 12/22/11 */ #include #define BRIGHTNESS_INCREMENT 64 /* Find pixel indices: max,mid,min */ static void sort_pixels(int *color, int *i) { if( color[0] > color[1] ) { if( color[1] > color[2] ) { i[0] = 0; i[1] = 1; i[2] = 2; } else if( color[0] > color[2] ) { i[0] = 0; i[1] = 2; i[2] = 1; } else { i[0] = 2; i[1] = 0; i[2] = 1; } } else { if( color[0] > color[2] ) { i[0] = 1; i[1] = 0; i[2] = 2; } else if( color[1] > color[2] ) { i[0] = 1; i[1] = 2; i[2] = 0; } else { i[0] = 2; i[1] = 1; i[2] = 0; } } } int main(int argc, char **argv) { FILE *infile = stdin; FILE *outfile = stdout; char buffer[1024]; int width, height, range, size; int i, c, color[3], index[3]; float chroma, scale; /* Open files */ if( argc > 1 && (argv[1][0] != '-' || argv[1][1] != '\0') ) { if( (infile = fopen(argv[1], "rb")) == NULL ) return printf("Can not open %s for reading\n", argv[1]); } if( argc > 2 && (argv[2][0] != '-' || argv[2][1] != '\0') ) { if( (outfile = fopen(argv[2], "wb+")) == NULL ) return printf("Can not open %s for writing\n", argv[2]); } /* Read header */ size = fread(buffer, 1, 1024, infile); if( size < 2 || buffer[0] != 'P' || buffer[1] != '6' || sscanf(buffer, "P6 %d %d %d", &width, &height, &range) != 3 || range != 255 ) { printf("Error parsing header from %s\n", argv[1]); fclose(infile); fclose(outfile); return 1; } /* Write header to output */ fprintf(outfile, "P6\n%d %d\n%d\n", width, height, range); /* Skip header */ c = 0; for(i = 0; i < size; i++) { if( buffer[i] == '\n' ) { if( ++c == 3 ) break; } } if( c < 3 ) { printf("Error parsing header from %s\n", argv[1]); fclose(infile); fclose(outfile); return 1; } /* Read bytes */ for(i++;;) { /* Read 3 pixels at once */ for(c = 0; c < 3; c++) { if( i == size ) { if( (size = fread(buffer, 1, 1024, infile)) == 0 ) break; i = 0; } color[c] = (int)(buffer[i++]) & 255; } if( size == 0 ) break; /* Compute chroma */ sort_pixels(color, index); /* Raise brightness */ color[0] += BRIGHTNESS_INCREMENT; color[1] += BRIGHTNESS_INCREMENT; color[2] += BRIGHTNESS_INCREMENT; if( color[index[0]] > 255 ) { if( color[index[2]] < 255 ) { /* Some (but not all) pixels exceeded valid range, adjust mid pixel to preserve chroma. */ chroma = (float)(color[index[1]] - color[index[2]]) / (float)(color[index[0]] - color[index[2]]); scale = (float)(255 - color[index[2]]) / (float)(color[index[0]] - color[index[2]]); color[index[1]] = (int)(color[index[2]] + chroma * scale); } if( color[0] > 255 ) color[0] = 255; if( color[1] > 255 ) color[1] = 255; if( color[2] > 255 ) color[2] = 255; } /* Output pixels */ fputc(color[0], outfile); fputc(color[1], outfile); fputc(color[2], outfile); } /* Cleanup */ fclose(infile); fclose(outfile); return 0; }