/* chinatsu.c - Don Yang (uguu.org) 01/02/12 */ #include #include int main(int argc, char **argv) { FILE *file[3]; int width[2], height[2], offset[2], c, x, y, x0, y0, step, ip0, ip1, iq0, iq1, best[4], z[4], scale[4], best_area, z_area, index[2][3][4] = { { {6, 9, 0, 3}, {1, 10, 4, 7}, {5, 11, 2, 8} }, { {3, 0, 6, 9}, {10, 1, 4, 7}, {8, 2, 5, 11} } }; float q, fpixel[12]; unsigned char *buffer[2], pixel[12], pixels[256][256]; if( argc < 4 ) printf("%s [odd]\n", *argv); else { for(x = 0, step = SEEK_SET; x < 2; x++) { if( !(file[x] = fopen(argv[x + 1], "rb")) ) goto error; fseek(file[x], 0, step); if( (int)fread(pixels[0], 1, 256, file[x]) < 1 || sscanf((char*)pixels[0], "P6\n%d %d\n%d", &width[x], &height[x], &y) - 3 || y - 255 ) goto error; for(y = c = offset[x] = 0; y < 256 && !offset[x]; y++) if( pixels[0][y] == '\n' ) if( ++c == 3 ) fseek(file[x], offset[x] = y + 1, step); if( !offset[x] || !(buffer[x] = (unsigned char*)malloc(width[x] * 3)) ) goto error; } if( width[0] - width[1] || height[0] - height[1] ) goto size; for(x = 0; x < 256; x++) for(y = 0; y < 256; y++) pixels[x][y] = 0; for(y = 0; y < *height; y++) { for(x = 0; x < 2; x++) if( fread(buffer[x], *width * 3, 1, file[x]) - 1 ) goto error; for(x = 0; x < *width * 3; x++) pixels[buffer[0][x]][buffer[1][x]] = 1; } best[0] = best[2] = scale[0] = scale[2] = 64; best[1] = best[3] = scale[1] = scale[3] = 256 - 64; best_area = (best[1] - best[0]) * (best[3] - best[2]); for(step = 64; step > 0; step /= 2) { for(ip0 = -1; ip0 < 1; ip0++) { z[0] = scale[0] + ip0 * step; if( z[0] > -1 ) for(iq0 = -1; iq0 < 1; iq0++) { z[2] = scale[2] + iq0 * step; if( z[2] > -1 ) for(ip1 = 1; ip1 > -1; ip1--) { z[1] = scale[1] + ip1 * step; if( z[1] < 257 ) for(iq1 = 1; iq1 > -1; iq1--) { z[3] = scale[3] + iq1 * step; if( z[3] < 257 ) { z_area = (z[1] - z[0]) * (z[3] - z[2]); if( z_area > best_area ) { for(x = c = 0; x < 256 && c > -1 && c < 256; x++) { x0 = x * (z[1] - z[0]) / 256 + z[0]; for(y = 0; y < 256 && c > -1 && c < 256; y++) { y0 = y * (z[3] - z[2]) / 256 + z[2]; if( pixels[x][y] ) c = (3 * x0 - y0) / 2; } } if( c > -1 && c < 256 ) { for(c = 0; c < 4; c++) best[c] = z[c]; best_area = z_area; } } } } } } } for(c = 0; c < 4; c++) scale[c] = best[c]; } if( !(file[2] = fopen(argv[3], "wb+")) ) goto error; else { fprintf(file[2], "P6\n%d %d\n255\n", *width * 2, *height * 2); for(x = 0; x < 2; x++) fseek(file[x], offset[x], SEEK_SET); c = argc > 4 ? 1 : 0; for(y = 0; y < *height; y++) { for(x = 0; x < 2; x++) if( fread(buffer[x], *width * 3, 1, file[x]) - 1 ) goto error; for(step = 0; step < 7; step += 6) for(x = 0; x < *width; x++) { for(x0 = 0; x0 < 3; x0++) { for(y0 = 0; y0 < 2; y0++) fpixel[index[c][x0][y0]] = buffer[y0][x * 3 + x0] * (scale[y0 * 2 + 1] - scale[y0 * 2]) / 256.f + scale[y0 * 2]; fpixel[index[c][x0][2]] = fpixel[index[c][x0][3]] = (3 * fpixel[index[c][x0][0]] - fpixel[index[c][x0][1]]) / 2; } for(x0 = 0; x0 < 12; x0++) { ip0 = fpixel[x0]; q = fpixel[x0] - ip0; if( rand() / (float)RAND_MAX < q ) ip0++; pixel[x0] = ip0 < 0 ? 0 : (ip0 > 255 ? 255 : ip0); } fwrite(pixel + step, 6, 1, file[2]); } } } } for(x = 0; x < 2; fclose(file[x++])) free(buffer[x]); return fclose(file[2]); size: printf("size "); error: return !puts("error"); }