7
#define noDUMP_FILE_NAME "dump.ebdp"
9
#define LITTLE_ENDIAN /* Needed for PSD support */
10
//#define TEST_PSD_DUMP
12
/* PSD structure. Since this data can be compressed planar data we need an object
13
to maintain our context state. */
22
int *band_row_length_index;
23
long *band_file_offset;
25
void (*read_line)(ETS_SrcPixel **ibufs, int xs, FILE *fi, int planes, void *image_ctx);
26
void (*write_line)(uchar **obufs, int xs, FILE *fo, int planes, void *image_ctx);
27
void (*finalize)(void *image_ctx);
31
typedef struct psd_ctx_s psd_ctx_t;
36
fprintf(stderr, "%s\n", why);
40
#define MAX_SIZE 65536
44
static const char * get_arg (int argc, char **argv, int *pi, const char *arg)
58
static int usage (void)
60
printf("Usage: ETS\n");
61
printf("ETS <options>\n");
62
printf(" -i <inputfile .pam or .pgm - omit for stdin\n");
63
printf(" -o <outputfile> same format as input - omit for stdout\n");
64
printf(" -g <gammafile> optional textual table of gamma values\n");
65
printf(" -e <style> ets style (0 off, 1 = normal, etc)\n");
66
printf(" -r <style> random noise style (0 off, 1 = rnd, 2 = tm\n");
67
printf(" -m <0 or 1> enable/disable multiplane optimisations\n");
68
printf(" -l <levels> number of levels in the output\n");
69
printf(" -a X:Y aspect ratio of input\n");
70
printf(" -n <noise level> noise level (0 to 8)\n");
71
printf("\n\nDefaults: -e1 -r1 -m1 -l2 -a1:1 -n0\n");
75
static void get4(int *value, uchar *buf)
78
*value = buf[3] + (buf[2] << 8) + (buf[1] << 16) + (buf[0] << 24);
80
*value = buf[0] + (buf[1] << 8) + (buf[2] << 16) + (buf[3] << 24);
84
static void get2(int *value, uchar *buf)
87
*value = buf[1] + (buf[0] << 8);
89
*value = buf[0] + (buf[1] << 8);
93
/* PSD uses PackBits RLE */
94
static void rle_decode(uchar *in_buff, int in_length,
95
uchar *out_buff, int out_length)
97
signed char hvalue, *input_buf;
99
int in_pos = 0, out_pos = 0;
101
input_buf = (signed char*) in_buff;
102
while (out_pos < out_length)
104
hvalue = input_buf[in_pos];
107
/* 1+hvalue literal bytes follow */
108
memcpy(&(out_buff[out_pos]), &(in_buff[in_pos + 1]), (1 + hvalue));
109
in_pos += (1 + (1 + hvalue));
110
out_pos += (1 + hvalue);
112
else if (hvalue > -128)
114
/* Repeat next byte 1-n times */
115
value = in_buff[in_pos+1];
116
memset(&(out_buff[out_pos]), value, (1 - hvalue));
118
out_pos += (1 - hvalue);
125
/* Photoshop RLE 8 bit case */
126
static void read_psd_line_rle8(ETS_SrcPixel **ibufs, int xs, FILE *fi, int planes,
130
psd_ctx_t *psd_ctx = (psd_ctx_t*) image_ctx;
131
long curr_file_offset;
132
int curr_row_length_index;
135
/* Loop across each band */
136
for (kk = 0; kk < planes; kk++)
138
/* Get a pointer and a length for the current one */
139
curr_file_offset = psd_ctx->band_file_offset[kk];
140
curr_row_length_index = psd_ctx->band_row_length_index[kk];
141
curr_length = psd_ctx->row_lengths[curr_row_length_index];
142
/* Get to where we are located in the file, read and decode */
143
fseek(fi, curr_file_offset, SEEK_SET);
144
fread(psd_ctx->rle_row, 1, curr_length, fi);
145
rle_decode((uchar*) psd_ctx->rle_row, curr_length, ibufs[psd_ctx->permute[kk]],
147
/* Update where we are in each band */
148
psd_ctx->band_file_offset[kk] += curr_length;
149
psd_ctx->band_row_length_index[kk] += 1;
153
/* Photoshop unencoded 8 bit case */
154
static void read_psd_line8(ETS_SrcPixel **ibufs, int xs, FILE *fi, int planes,
158
psd_ctx_t *psd_ctx = (psd_ctx_t*) image_ctx;
159
long curr_file_offset;
160
int curr_length = psd_ctx->width;
162
/* Loop across each band */
163
for (kk = 0; kk < planes; kk++)
165
/* Get a pointer and a length for the current one */
166
curr_file_offset = psd_ctx->band_file_offset[kk];
167
/* Get to where we are located in the file, read and decode */
168
fseek(fi, curr_file_offset, SEEK_SET);
169
fread(ibufs[psd_ctx->permute[kk]], 1, curr_length, fi);
170
/* Update where we are in each band */
171
psd_ctx->band_file_offset[kk] += curr_length;
175
/* Photoshop 8 bit unencoded output. Due to its planar form, this is stored in a
176
temp buffer until we reach the final line, at which point we write out the
178
static void write_psd_line8(uchar **obufs, int xs, FILE *fo, int planes,
182
psd_ctx_t *psd_ctx = (psd_ctx_t*) image_ctx;
183
const void *input_buf;
184
uchar *output_buff = (uchar*) psd_ctx->output_buffer;
185
long plane_size = (psd_ctx->width) * (psd_ctx->height);
186
long buffer_size = plane_size * planes;
188
output_buff += ((psd_ctx->curr_row) * (psd_ctx->width));
189
for (kk = 0; kk < planes; kk++)
191
input_buf = (const void*) obufs[psd_ctx->permute[kk]];
192
memcpy(output_buff, input_buf, psd_ctx->width);
193
output_buff += plane_size;
195
psd_ctx->curr_row += 1;
196
/* If at end, then dump the buffer */
197
if (psd_ctx->curr_row == psd_ctx->height)
198
fwrite(psd_ctx->output_buffer, 1, buffer_size, fo);
201
/* Photoshop unencoded 16 bit case */
202
static void read_psd_line16(ETS_SrcPixel **ibufs, int xs, FILE *fi, int planes,
206
psd_ctx_t *psd_ctx = (psd_ctx_t*) image_ctx;
207
long curr_file_offset;
208
int curr_length = psd_ctx->width * 2;
210
unsigned short temp_value1, temp_value2;
212
/* Loop across each band */
213
for (kk = 0; kk < planes; kk++)
215
/* Get a pointer and a length for the current one */
216
curr_file_offset = psd_ctx->band_file_offset[kk];
217
/* Get to where we are located in the file, read and decode */
218
fseek(fi, curr_file_offset, SEEK_SET);
219
fread(ibufs[psd_ctx->permute[kk]], 1, curr_length, fi);
221
for (i = 0; i < psd_ctx->width; i++)
223
temp_value1 = ibufs[psd_ctx->permute[kk]][i];
224
temp_value2 = ((temp_value1 & 0xff) << 8) + ((temp_value1 & 0xff00) >> 8);
225
ibufs[psd_ctx->permute[kk]][i] = temp_value2;
228
/* Update where we are in each band */
229
psd_ctx->band_file_offset[kk] += curr_length;
233
/* Photoshop 16 bit unencoded output. Due to its planar form, this is stored in a
234
temp buffer until we reach the final line, at which point we write out the entire
235
thing. This is not used really, but here for completeness and some testing.
236
Needs fix for little endian */
237
static void write_psd_line16(uchar **obufs, int xs, FILE *fo, int planes,
241
psd_ctx_t *psd_ctx = (psd_ctx_t*) image_ctx;
242
const void *input_buf;
243
uchar *output_buff = (uchar*) psd_ctx->output_buffer;
244
long plane_size = (psd_ctx->width) * (psd_ctx->height) * 2;
245
long buffer_size = plane_size * planes;
247
output_buff += ((psd_ctx->curr_row) * (psd_ctx->width)) * 2;
248
for (kk = 0; kk < planes; kk++)
250
input_buf = (const void*) obufs[psd_ctx->permute[kk]];
251
memcpy(output_buff, input_buf, psd_ctx->width * 2);
252
output_buff += plane_size;
254
psd_ctx->curr_row += 1;
255
/* If at end, then dump the buffer */
256
if (psd_ctx->curr_row == psd_ctx->height)
257
fwrite(psd_ctx->output_buffer, 1, buffer_size, fo);
260
static void finalize_psd(void *image_ctx)
262
psd_ctx_t *psd_ctx = (psd_ctx_t*) image_ctx;
264
if (psd_ctx->output_buffer != NULL)
265
free(psd_ctx->output_buffer);
266
if (psd_ctx->band_row_length_index != NULL)
267
free(psd_ctx->band_row_length_index);
268
if (psd_ctx->band_file_offset != NULL)
269
free(psd_ctx->band_file_offset);
270
if (psd_ctx->rle_row != NULL)
271
free(psd_ctx->rle_row);
272
if (psd_ctx->permute != NULL)
273
free(psd_ctx->permute);
276
static void read_psd(FILE *fi, psd_ctx_t *psd_ctx, FILE *fo)
281
int height, width, color_mode;
287
int codec, maxlength = 0;
292
uchar *in_buff, *out_buff;
295
psd_ctx->curr_row = 0;
297
/* rewind and get the header information */
300
fread(buf, 1, 26, fi);
303
num_channel = buf[13];
304
get4(&height, &(buf[14]));
305
get4(&width, &(buf[18]));
308
color_mode = buf[25];
310
if (!(depth == 8 || depth == 16))
311
die("Only 8 or 16 bit PSD files supported");
313
if (depth == 16 && (sizeof(ETS_SrcPixel) != 2 || ETS_SRC_MAX != 65535))
314
die("ETS_SrcPixel type and ETS_SRC_MAX in ets.h not set for 16 bit support!");
316
if (depth == 8 && (sizeof(ETS_SrcPixel) != 1 || ETS_SRC_MAX != 255))
317
die("ETS_SrcPixel type and ETS_SRC_MAX in ets.h not set for 8 bit support!");
319
/* Dont handle duotone or indexed data at this time */
320
if (color_mode == 2 || color_mode == 8)
321
die("Indexed and Duotone PSD files not supported");
323
psd_ctx->depth = depth;
324
psd_ctx->height = height;
325
psd_ctx->width = width;
326
psd_ctx->num_channels = num_channel;
333
/* Change the output to 8 bit */
336
/* Write out the header information */
337
fwrite(buf, 1, 26, fo);
339
/* Index or duotone information */
340
fread(buf, 1, 4, fi);
341
fwrite(buf, 1, 4, fo);
344
/* Record information. Pass along... */
345
fread(buf, 1, 4, fi);
347
fwrite(buf, 1, 4, fo);
348
temp_buff = (uchar*) malloc(size);
349
fread(temp_buff, 1, size, fi);
350
fwrite(temp_buff, 1, size, fo);
354
/* Layer information. Pass along... */
355
fread(buf, 1, 4, fi);
357
fwrite(buf, 1, 4, fo);
358
temp_buff = (uchar*) malloc(size);
359
fread(temp_buff, 1, size, fi);
360
fwrite(temp_buff, 1, size, fo);
364
/* Image information. The stuff we want. Only support raw or RLE types for
365
input. Output is uncompressed */
366
fread(buf, 1, 2, fi);
368
if (!(codec == 0 || codec == 1))
369
die("ZIP data in PSD files not supported");
372
fwrite(buf, 1, 2, fo);
375
if (codec == 1 && depth == 16)
376
die("PSD RLE 16 bit files not supported");
378
/* Allocate the output buffer */
379
psd_ctx->output_buffer = malloc(num_channel * height * width * bytes);
383
/* RLE. Need to decompress the data. Each scan line is individually
384
compressed. First read in the size for each compressed line */
385
data_size = num_channel * height;
386
psd_ctx->row_lengths = (int*) malloc(data_size * sizeof(int));
387
psd_ctx->band_file_offset = (long*) malloc(num_channel * sizeof(long));
388
psd_ctx->band_row_length_index = (int*) malloc(num_channel * sizeof(int));
389
count += (2 * data_size); /* This gets us to the start of the image data */
390
/* Here we compute where in the file we need to go, to get the start of
391
the scan line in each band, we compute the max length of all the
392
encoded bands and get the length of each encoded band */
393
for (jj = 0; jj < num_channel; jj++)
395
(psd_ctx->band_file_offset)[jj] = count + curr_count;
396
for (kk = 0; kk < height; kk++)
398
fread(buf, 1, 2, fi);
399
get2(&((psd_ctx->row_lengths)[index]), buf);
400
if (maxlength < (psd_ctx->row_lengths)[index])
401
maxlength = (psd_ctx->row_lengths)[index];
402
curr_count = curr_count + (psd_ctx->row_lengths)[index];
406
psd_ctx->rle_row = (void*) malloc(maxlength);
407
psd_ctx->read_line = read_psd_line_rle8;
408
psd_ctx->write_line = write_psd_line8;
409
for (kk = 0; kk < num_channel; kk++)
411
(psd_ctx->band_row_length_index)[kk] = kk * height;
414
/* Now do the decode for testing */
415
in_buff = (uchar*) malloc(maxlength);
416
out_buff = (uchar*) malloc(width);
417
for (kk = 0; kk < data_size; kk++)
419
fread(in_buff, 1, (psd_ctx->row_lengths)[kk], fi);
420
rle_decode(in_buff, (psd_ctx->row_lengths)[kk], out_buff, width);
421
fwrite(out_buff, 1, width, fo);
431
/* Uncompressed data. Read directly */
432
psd_ctx->row_lengths = NULL;
433
psd_ctx->rle_row = NULL;
434
psd_ctx->band_row_length_index = NULL;
435
psd_ctx->band_file_offset = (long*) malloc(num_channel * sizeof(long));
436
for (kk = 0; kk < num_channel; kk++)
438
(psd_ctx->band_file_offset)[kk] = count + height * width * kk * bytes;
442
psd_ctx->read_line = read_psd_line8;
443
psd_ctx->write_line = write_psd_line8;
447
psd_ctx->read_line = read_psd_line16;
448
psd_ctx->write_line = write_psd_line8;
451
psd_ctx->finalize = finalize_psd;
452
psd_ctx->permute = (uchar*) malloc(num_channel);
453
/* A default initialization */
454
for (kk = 0; kk < num_channel; kk++)
456
psd_ctx->permute[kk] = kk;
460
static void read_pgm(FILE *fi, int *xs, int *ys, FILE *fo)
466
fgets(buf, sizeof(buf), fi);
467
while (buf[0] == '#');
468
sscanf (buf, "%d", xs);
470
fgets (buf, sizeof(buf), fi);
471
while (buf[0] == '#');
472
sscanf (buf, "%d", ys);
473
if (*xs <= 0 || *ys <= 0 || *xs > MAX_SIZE || *ys > MAX_SIZE)
474
die("Input image size out of range");
477
fgets(buf, sizeof(buf), fi);
478
while (buf[0] == '#');
479
sscanf(buf, "%d", &depth);
481
die("Only works with depth=255 images");
483
fprintf(fo, "P5\n%d %d\n255\n", *xs, *ys);
486
static int read_pam(FILE *fi, int *xs, int *ys, FILE *fo)
496
fgets(buf, sizeof(buf), fi);
499
fprintf(fo, "%s", buf);
502
if (buf[0] == '\n' || buf[0] == '\r')
504
if (sscanf(buf, "WIDTH %d", xs))
506
fprintf(fo, "WIDTH %d\n", *xs);
508
else if (sscanf(buf, "HEIGHT %d", ys))
510
fprintf(fo, "HEIGHT %d\n", *ys);
512
else if (sscanf(buf, "DEPTH %d", &depth))
515
die("Only CMYK/DEVN pams supported");
516
fprintf(fo, "DEPTH %d\n", depth);
518
else if (sscanf(buf, "MAXVAL %d", &i))
521
die("Only pams with MAXVAL=255 supported");
522
fprintf(fo, "MAXVAL 255\n");
524
else if (sscanf(buf, "TUPLTYPE DEV%c", &c) && c == 'N')
526
fprintf(fo, "TUPLTYPE DEVN\n");
528
else if (sscanf(buf, "TUPLTYPE CMY%c", &c) && c == 'K')
530
fprintf(fo, "TUPLTYPE CMYK\n");
532
else if (sscanf(buf, "TUPLTYP%c") && c == 'E')
534
die("Only CMYK/DEVN pams supported");
536
else if (sscanf(buf, "ENDHD%c", &c) && c == 'R')
538
fprintf(fo, "ENDHDR\n");
543
printf(stderr, "Unknown header field: %s\n", buf);
544
die("Unknown header field\n");
552
static void read_pgm_line(ETS_SrcPixel **ibufs, int xs, FILE *fi, int planes,
556
nbytes = fread(ibufs[0], 1, xs, fi);
558
die("Error reading image (file truncated?)");
561
static void read_pam_line(ETS_SrcPixel **ibufs, int xs, FILE *fi, int planes,
566
for (i = 0; i < xs && c != EOF; i++)
568
ibufs[1][i] = 255-fgetc(fi);
569
ibufs[2][i] = 255-fgetc(fi);
570
ibufs[3][i] = 255-fgetc(fi);
571
ibufs[0][i] = 255-(c = fgetc(fi));
572
for (j=4; j < planes; j++)
573
ibufs[j][i] = 255-(c = fgetc(fi));
576
die("Error reading image (file truncated?)");
579
static void write_pgm_line(uchar **obufs, int xs, FILE *fo, int planes,
582
fwrite(obufs[0], 1, xs, fo);
585
static void write_pam_line(uchar **obufs, int xs, FILE *fo, int planes,
590
for (i = 0; i < xs; i++)
592
fputc(255-obufs[1][i], fo);
593
fputc(255-obufs[2][i], fo);
594
fputc(255-obufs[3][i], fo);
595
fputc(255-obufs[0][i], fo);
596
for (j = 4; j < planes; j++)
598
fputc(255-obufs[j][i], fo);
604
main(int argc, char **argv)
611
ETS_POLARITY polarity;
614
int lut[ETS_SRC_MAX+1], i;
616
int rs_lut[ETS_SRC_MAX+1];
618
int strengths[M][M] = { { 0 },
621
{ 128, 51, 51, 13 }, // KCMY
623
{ 128, 51, 51, 13, 13, 13 }, // KCMYcm
624
{ 128, 51, 51, 13, 13, 13, 13 }, // KCMYcmk
625
{ 128, 51, 51, 13, 13, 13, 13, 13}, // KCMYcmkk
627
/* Used now in PSD case so that we can reorder the planes according to the above weights */
628
uchar permutes[M][M] = { { 0 },
631
{ 3, 0, 1, 2 }, // KCMY
633
{ 3, 0, 1, 2, 4, 5 }, // KCMYcm
634
{ 3, 0, 1, 2, 4, 5, 6 }, // KCMYcmk
635
{3, 0, 1, 2, 4, 5, 6, 7}, // KCMYcmkk
637
int c1_scale[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 };
638
ETS_SrcPixel *ibufs[M] = { 0 };
639
uchar *obufs[M] = { 0 };
641
void (*read_line)(ETS_SrcPixel **ibufs, int xs, FILE *fi, int planes, void *image_ctx);
642
void (*write_line)(uchar **obufs, int xs, FILE *fo, int planes, void *image_ctx);
643
void (*finalize)(void *image_ctx);
644
char *gamma_tab = NULL;
653
void *image_ctx = NULL;
654
uchar byte_count = 1;
658
for (i = 1; i < argc; i++)
660
const char *arg = argv[i];
661
const char *arg_value;
665
if ((arg_value = get_arg(argc, argv, &i, arg + 2)) == NULL)
671
fi = fopen(arg_value,"rb");
673
die ("Input not found");
676
fo = fopen(arg_value,"wb");
678
die ("Output failed to open");
681
gamma_tab = arg_value;
684
multiplane = atoi(arg_value);
687
levels = atoi(arg_value);
690
ets_style = atoi(arg_value);
693
r_style = atoi(arg_value);
696
noise = atoi(arg_value);
699
sscanf(arg_value, "%d:%d", &aspect_x, &aspect_y);
707
fgets(buf, sizeof(buf), fi);
709
if (buf[0] == 'P' && buf[1] == '5')
711
read_pgm(fi, &xs, &ys, fo);
712
read_line = read_pgm_line;
713
write_line = write_pgm_line;
716
polarity = ETS_BLACK_IS_ZERO;
718
else if (buf[0] == 'P' && buf[1] == '7')
720
planes = read_pam(fi, &xs, &ys, fo);
721
read_line = read_pam_line;
722
write_line = write_pam_line;
724
polarity = ETS_BLACK_IS_ZERO;
726
else if (buf[0] == '8' && buf[1] == 'B' && buf[2] == 'P' && buf[3] == 'S')
728
read_psd(fi, &psd_ctx, fo);
729
read_line = psd_ctx.read_line;
730
write_line = psd_ctx.write_line;
731
finalize = psd_ctx.finalize;
732
planes = psd_ctx.num_channels;
735
image_ctx = (void*) &psd_ctx;
736
if (psd_ctx.depth == 16)
738
polarity = ETS_BLACK_IS_ONE;
739
/* Set the read and write permutation order according to permutes array */
740
if (permutes[planes-1] != 0)
742
int sum = 0; /* an error check */
743
for (i = 0; i < planes; i++)
745
psd_ctx.permute[i] = permutes[planes-1][i];
746
sum += psd_ctx.permute[i];
748
if (sum != ((float) planes/2.0) * (float) (planes - 1.0))
749
die ("Permutation vector values are not valid");
753
die("Need pgmraw, pamraw or psd image on input");
756
for (i = 0; i < planes; i++)
758
ibufs[i] = (ETS_SrcPixel*) malloc(xs * byte_count);
759
obufs[i] = (uchar*) ets_malloc_aligned(xsb + 16, 16);
762
/* This sets up a simple gamma lookup table. */
765
FILE *lutf = fopen(gamma_tab, "r");
766
for (i = 0; i < (ETS_SRC_MAX+1); i++)
767
fscanf(lutf, "%d", &lut[i]);
772
double scale = ETS_SRC_MAX;
773
for (i = 0; i < (ETS_SRC_MAX+1); i++)
775
lut[i] = (int)((1 << 24) * (pow (i / scale, 1.0)));
777
lut[i] = (1 << 24) * (0.88 + 0.02 * i / 255.0);
781
for (i = 0; i < (ETS_SRC_MAX+1); i++)
784
#ifdef DUMP_FILE_NAME
785
params.dump_file = fopen(DUMP_FILE_NAME, "wb");
787
params.dump_file = NULL;
789
params.dump_level = ETS_DUMP_ALL;
792
params.n_planes = planes;
793
params.levels = levels;
794
for (i = 0; i < planes; i++)
797
params.strengths = (multiplane ? strengths[planes-1] : strengths[0]);
798
params.aspect_x = aspect_x;
799
params.aspect_y = aspect_y;
800
params.distscale = 0;
801
params.rand_scale = noise;
802
params.c1_scale = c1_scale;
803
params.ets_style = ets_style;
804
params.r_style = r_style;
805
params.polarity = polarity;
806
for (i = 0; i < planes; i++)
808
params.rand_scale_luts = rs_luts;
809
params.rand_scale_luts = NULL;
810
ctx = ets_new(¶ms);
811
for (y = 0; y < ys; y++)
815
read_line(ibufs, xs, fi, planes, image_ctx);
816
ets_line(ctx, obufs, (const ETS_SrcPixel *const *)&ibufs);
818
for (i = 0; i < planes; i++)
820
uchar *obuf = obufs[i];
821
if (polarity == ETS_BLACK_IS_ONE)
823
for (x = 0; x < xs; x++)
825
obuf[x] = obuf[x] * 255 / (params.levels - 1);
830
for (x = 0; x < xs; x++)
832
obuf[x] = 255 - obuf[x] * 255 / (params.levels - 1);
836
write_line(obufs, xs, fo, planes, image_ctx);
838
if (finalize != NULL)
842
for (i=0; i < planes; i++)
844
ets_free_aligned(obufs[i]);