#include #include #include #include #include struct yjk { int16_t y; int16_t j; int16_t k; } __attribute__((packed)); struct rgb { uint8_t r; uint8_t g; uint8_t b; } __attribute__((packed)); static void rgb2yjk(struct rgb *in, struct yjk *out) { int16_t y, j, k; // YJKは(本来の値×8)としている y = in->b * 4 + in->r * 2 + in->g; j = in->r * 8 - y; k = in->g * 8 - y; out->y = le16toh(y); out->j = le16toh(j); out->k = le16toh(k); } static void yjk2rgb(struct yjk *in, struct rgb *out) { int r, g, b; int16_t y, j, k; y = le16toh(in->y); j = le16toh(in->j); k = le16toh(in->k); r = (y + j) / 8; g = (y + k) / 8; b = (y * 5 - j * 2 - k) / 32; if (r < 0) r = 0; else if (r > UINT8_MAX) r = UINT8_MAX; if (g < 0) g = 0; else if (g > UINT8_MAX) g = UINT8_MAX; if (b < 0) b = 0; else if (b > UINT8_MAX) b = UINT8_MAX; out->r = r; out->g = g; out->b = b; } static void encyjk(FILE *fpi, FILE *fpo) { struct rgb rgb; struct yjk yjk; while (1) { if (fread(&rgb, 1, sizeof(rgb), fpi) < sizeof(rgb)) break; rgb2yjk(&rgb, &yjk); if (fwrite(&yjk, sizeof(yjk), 1, fpo) < 1) { fprintf(stderr, "encyjk: file write error\n"); break; } } } static void encrgb(FILE *fpi, FILE *fpo) { struct yjk yjk; struct rgb rgb; while (1) { if (fread(&yjk, 1, sizeof(yjk), fpi) < sizeof(yjk)) break; yjk2rgb(&yjk, &rgb); if (fwrite(&rgb, sizeof(rgb), 1, fpo) < 1) { fprintf(stderr, "encrgb: file write error\n"); break; } } } int main(int argc, char *argv[]) { FILE *fpi, *fpo; if (argc < 2 || (*argv[1] != 'y' && *argv[1] != 'r')) { fprintf(stderr, "usage: %s [command] [(infile)] [(outfile)]\n", argv[0]); fprintf(stderr, " command y RGB -> YJK\n"); fprintf(stderr, " r YJK -> RGB\n"); goto fin0; } if (argc < 3 || !strcmp(argv[2], "-")) { fpi = stdin; } else { fpi = fopen(argv[2], "r"); if (fpi == NULL) { fprintf(stderr, "file open error (in)\n"); goto fin0; } } if (argc < 4 || !strcmp(argv[3], "-")) { fpo = stdout; } else { fpo = fopen(argv[3], "w"); if (fpo == NULL) { fprintf(stderr, "file open error (out)\n"); goto fin1; } } switch (*argv[1]) { case 'y': encyjk(fpi, fpo); break; case 'r': encrgb(fpi, fpo); break; } //fin2: if (fpo != stdout) fclose(fpo); fin1: if (fpi != stdin) fclose(fpi); fin0: return 0; }