/* Transform an entire buffer */ int gscms_transform_color_buffer(gx_device *dev, gsicc_link_t *icclink, gsicc_bufferdesc_t *input_buff_desc, gsicc_bufferdesc_t *output_buff_desc, void *inputbuffer, void *outputbuffer) { cmsHTRANSFORM hTransform = (cmsHTRANSFORM) icclink->link_handle; DWORD dwInputFormat,dwOutputFormat,curr_input,curr_output; int planar,numbytes,big_endian,hasalpha,k; unsigned char *inputpos, *outputpos; int numchannels; #if DUMP_CMS_BUFFER FILE *fid_in, *fid_out; #endif /* Although little CMS does make assumptions about data types in its transformations you can change it after the fact. */ /* Set us to the proper output type */ /* Note, we could speed this up by passing back the encoded data type to the caller so that we could avoid having to go through this computation each time if they are doing multiple calls to this operation */ _LPcmsTRANSFORM p = (_LPcmsTRANSFORM) (LPSTR) hTransform; curr_input = p->InputFormat; curr_output = p->OutputFormat; /* Color space MUST be the same */ dwInputFormat = COLORSPACE_SH(T_COLORSPACE(curr_input)); dwOutputFormat = COLORSPACE_SH(T_COLORSPACE(curr_output)); /* Now set if we have planar, num bytes, endian case, and alpha data to skip */ /* Planar -- pdf14 case for example */ planar = input_buff_desc->is_planar; dwInputFormat = dwInputFormat | PLANAR_SH(planar); planar = output_buff_desc->is_planar; dwOutputFormat = dwOutputFormat | PLANAR_SH(planar); /* 8 or 16 byte input and output */ numbytes = input_buff_desc->bytes_per_chan; if (numbytes>2) numbytes = 0; /* littleCMS encodes float with 0 ToDO. */ dwInputFormat = dwInputFormat | BYTES_SH(numbytes); numbytes = output_buff_desc->bytes_per_chan; if (numbytes>2) numbytes = 0; dwOutputFormat = dwOutputFormat | BYTES_SH(numbytes); /* endian */ big_endian = !input_buff_desc->little_endian; dwInputFormat = dwInputFormat | ENDIAN16_SH(big_endian); big_endian = !output_buff_desc->little_endian; dwOutputFormat = dwOutputFormat | ENDIAN16_SH(big_endian); /* number of channels */ numchannels = input_buff_desc->num_chan; dwInputFormat = dwInputFormat | CHANNELS_SH(numchannels); numchannels = output_buff_desc->num_chan; dwOutputFormat = dwOutputFormat | CHANNELS_SH(numchannels); /* alpha, which is passed through unmolested */ /* ToDo: Right now we always must have alpha last */ /* This is really only going to be an issue when we have interleaved alpha data */ hasalpha = input_buff_desc->has_alpha; dwInputFormat = dwInputFormat | EXTRA_SH(hasalpha); dwOutputFormat = dwOutputFormat | EXTRA_SH(hasalpha); /* Change the formaters */ cmsChangeBuffersFormat(hTransform,dwInputFormat,dwOutputFormat); /* littleCMS knows nothing about word boundarys. As such, we need to do this row by row adjusting for our stride. Output buffer must already be allocated. ToDo: Check issues with plane and row stride and word boundry */ inputpos = (unsigned char *) inputbuffer; outputpos = (unsigned char *) outputbuffer; if(input_buff_desc->is_planar){ /* Do entire buffer. Care must be taken here with respect to row stride, word boundry and number of source versus output channels. We may need to take a closer look at this. */ cmsDoTransform(hTransform,inputpos,outputpos, input_buff_desc->plane_stride); #if DUMP_CMS_BUFFER fid_in = gp_fopen("CM_Input.raw","ab"); fid_out = fp_fopen("CM_Output.raw","ab"); fwrite((unsigned char*) inputbuffer,sizeof(unsigned char), input_buff_desc->plane_stride * input_buff_desc->num_chan, fid_in); fwrite((unsigned char*) outputbuffer,sizeof(unsigned char), output_buff_desc->plane_stride * output_buff_desc->num_chan, fid_out); fclose(fid_in); fclose(fid_out); #endif } else { /* Do row by row. */ for(k = 0; k < input_buff_desc->num_rows ; k++){ cmsDoTransform(hTransform,inputpos,outputpos, input_buff_desc->pixels_per_row); inputpos += input_buff_desc->row_stride; outputpos += output_buff_desc->row_stride; } #if DUMP_CMS_BUFFER fid_in = gp_fopen("CM_Input.raw","ab"); fid_out = gp_fopen("CM_Output.raw","ab"); fwrite((unsigned char*) inputbuffer,sizeof(unsigned char), input_buff_desc->row_stride,fid_in); fwrite((unsigned char*) outputbuffer,sizeof(unsigned char), output_buff_desc->row_stride,fid_out); fclose(fid_in); fclose(fid_out); #endif } return 0; }
/* save_pcx: * Writes a bitmap into a PCX file, using the specified palette (this * should be an array of at least 256 RGB structures). */ int save_pcx (FILE* f, MYBITMAP *bmp, RGB *pal) { FILE *f; PALETTE tmppal; int c; int x, y; int runcount; int depth, planes; char runchar; char ch; if (!pal) { get_palette(tmppal); pal = tmppal; } f = fp_fopen(filename, F_WRITE); if (!f) return *allegro_errno; depth = bitmap_color_depth(bmp); if (depth == 8) planes = 1; else planes = 3; fp_putc(10, f); /* manufacturer */ fp_putc(5, f); /* version */ fp_putc(1, f); /* run length encoding */ fp_putc(8, f); /* 8 bits per pixel */ fp_iputw(0, f); /* xmin */ fp_iputw(0, f); /* ymin */ fp_iputw(bmp->w-1, f); /* xmax */ fp_iputw(bmp->h-1, f); /* ymax */ fp_iputw(320, f); /* HDpi */ fp_iputw(200, f); /* VDpi */ for (c=0; c<16; c++) { fp_putc(_rgb_scale_6[pal[c].r], f); fp_putc(_rgb_scale_6[pal[c].g], f); fp_putc(_rgb_scale_6[pal[c].b], f); } fp_putc(0, f); /* reserved */ fp_putc(planes, f); /* one or three color planes */ fp_iputw(bmp->w, f); /* number of bytes per scanline */ fp_iputw(1, f); /* color palette */ fp_iputw(bmp->w, f); /* hscreen size */ fp_iputw(bmp->h, f); /* vscreen size */ for (c=0; c<54; c++) /* filler */ fp_putc(0, f); for (y=0; y<bmp->h; y++) { /* for each scanline... */ runcount = 0; runchar = 0; for (x=0; x<bmp->w*planes; x++) { /* for each pixel... */ if (depth == 8) { ch = getpixel(bmp, x, y); } else { if (x<bmp->w) { c = getpixel(bmp, x, y); ch = getr_depth(depth, c); } else if (x<bmp->w*2) { c = getpixel(bmp, x-bmp->w, y); ch = getg_depth(depth, c); } else { c = getpixel(bmp, x-bmp->w*2, y); ch = getb_depth(depth, c); } } if (runcount==0) { runcount = 1; runchar = ch; } else { if ((ch != runchar) || (runcount >= 0x3f)) { if ((runcount > 1) || ((runchar & 0xC0) == 0xC0)) fp_putc(0xC0 | runcount, f); fp_putc(runchar,f); runcount = 1; runchar = ch; } else runcount++; } } if ((runcount > 1) || ((runchar & 0xC0) == 0xC0)) fp_putc(0xC0 | runcount, f); fp_putc(runchar,f); } if (depth == 8) { /* 256 color palette */ fp_putc(12, f); for (c=0; c<256; c++) { fp_putc(_rgb_scale_6[pal[c].r], f); fp_putc(_rgb_scale_6[pal[c].g], f); fp_putc(_rgb_scale_6[pal[c].b], f); } } fp_fclose(f); return *allegro_errno; }