Esempio n. 1
0
/* 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;
}
Esempio n. 2
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;
}