/* * This software is copyrighted as noted below. It may be freely copied, * modified, and redistributed, provided that the copyright notice is * preserved on all copies. * * There is no warranty or other guarantee of fitness for this software, * it is provided solely "as is". Bug reports or fixes may be sent * to the author, who may or may not act on them as he desires. * * You may not include this software in a program or other software product * without supplying the source, or without informing the end-user that the * source is available for no extra charge. * * If you modify this software, you should include a notice giving the * name of the person performing the modification, the date of modification, * and the reason for such modification. */ /* * rle.c - interface with Utah's rle images ( needs RLE library ). * * Author: Raul Rivero * Mathematics Dept. * University of Oviedo * Date: Fri Dec 27 1991 * Copyright (c) 1991, Raul Rivero * */ #include #include /* * Look here !!! * ============= * * This code is valid only if we have defined the iRLE * macro ( read the root Makefile for more information ). * */ #ifdef iRLE #include #define PSEUDOCOLOR 1 #define DIRECTCOLOR 2 #define TRUECOLOR 3 #define GRAYSCALE 4 extern int LUGverbose; /* * Define internal functions prototype. */ void rlecmap_to_bitmapcmap( #ifdef USE_PROTOTYPES rle_hdr *, bitmap_hdr * #endif ); void bitmapcmap_to_rlecmap( #ifdef USE_PROTOTYPES bitmap_hdr *, rle_hdr * #endif ); read_rle_file( name, bitmap ) char *name; bitmap_hdr *bitmap; { FILE *handle; /* Open the file descriptor */ if ( name != NULL ) handle = Fopen( name, "rb" ); else handle = stdin; /* Read the bitmap */ read_rle( handle, bitmap ); rm_compress(); /* Close the file */ Fclose( handle ); } read_rle(handle, image) FILE *handle; bitmap_hdr *image; { register int i, j; rle_pixel **row; byte *r, *g, *b; int totalsize; color_map *map; int type; int two_lines; int offset_last; /* * Read the file's configuration. */ rle_dflt_hdr.rle_file = handle; if ( rle_get_setup( &rle_dflt_hdr ) != RLE_SUCCESS ) error(3); /* * Fill our bitmap. */ image->magic = LUGUSED; image->xsize = rle_dflt_hdr.xmax - rle_dflt_hdr.xmin + 1; image->ysize = rle_dflt_hdr.ymax - rle_dflt_hdr.ymin + 1; image->depth = ( rle_dflt_hdr.ncolors < 3 ? rle_dflt_hdr.cmaplen : 24 ); image->colors = ( 1 << image->depth ); totalsize= image->xsize * image->ysize; offset_last = totalsize - image->xsize; two_lines = 2 * image->xsize; VPRINTF(stderr, "Image size: %dx%d\n", image->xsize, image->ysize); VPRINTF(stderr, "Image depth: %d\n", image->depth); VPRINTF(stderr, "%s colormap\n", (rle_dflt_hdr.ncmap ? "With" : "Without")); /* * Check the coherence and image type. */ VPRINTF(stderr, "Image type "); switch ( rle_dflt_hdr.ncolors ) { case 1: switch ( rle_dflt_hdr.ncmap ) { case 0: type = GRAYSCALE; /* 8 planes, no cmap */ VPRINTF(stderr, "GRAYSCALE\n"); break; case 3: type = PSEUDOCOLOR; /* 8 planes, cmap */ VPRINTF(stderr, "PSEUDOCOLOR\n"); break; default: error(6); VPRINTF(stderr, "unkown\n"); break; } break; case 3: switch ( rle_dflt_hdr.ncmap ) { case 0: type = DIRECTCOLOR; /* 24 planes, no cmap */ VPRINTF(stderr, "DIRECTCOLOR\n"); break; case 3: type = TRUECOLOR; /* 24 planes, cmap */ VPRINTF(stderr, "TRUECOLOR\n"); break; default: error(6); VPRINTF(stderr, "unkown\n"); break; } break; default: error(6); VPRINTF(stderr, "unkown\n"); break; } /* * Allocate some memory. */ if (rle_row_alloc(&rle_dflt_hdr, &row) < 0) error(2); if (image->depth > 8 || type == GRAYSCALE) { /* * 24 planes => we need three components * GRAYSCALE use 8 planes but it's defined like 24 planes */ r= image->r = (byte *) Malloc(totalsize); g= image->g = (byte *) Malloc(totalsize); b= image->b = (byte *) Malloc(totalsize); if ( type == TRUECOLOR) { image->colors = 256; /* well, a trap to rlecmap_to_bit... */ rlecmap_to_bitmapcmap(&rle_dflt_hdr, image); map = (color_map *) image->cmap; /* will be more easy use it */ } }else { /* 8 planes => one component and cmap */ r= image->r = (byte *) Malloc(totalsize); /* Convert rle cmap to bitmap cmap */ rlecmap_to_bitmapcmap(&rle_dflt_hdr, image); map = (color_map *) image->cmap; /* will be more easy use it */ } /* * Read the input image and convert it to a simple bitmap. * RLE writes lines in reverse order, so we point to last * line. */ VPRINTF(stderr, "Uncompressing RLE file\n"); r += offset_last; if ( type != PSEUDOCOLOR ) { g += offset_last; b += offset_last; } for (j= 0; j< image->ysize; j++) { rle_getrow(&rle_dflt_hdr, row); switch ( type ) { case GRAYSCALE : case DIRECTCOLOR: for (i= 0; i< image->xsize; i++) { *r++ = row[0][i]; *g++ = row[1][i]; *b++ = row[2][i]; } break; case PSEUDOCOLOR: for (i= 0; ixsize; i++) { *r++ = row[0][i]; } break; case TRUECOLOR : for (i= 0; i< image->xsize; i++) { *r++ = map[row[0][i]][0]; *g++ = map[row[1][i]][1]; *b++ = map[row[2][i]][i]; } break; default : error(6); break; } /* * Pointers to next byte of current line, so we substract * two lines. */ r -= two_lines; if ( type != PSEUDOCOLOR ) { g -= two_lines; b -= two_lines; } } /* * TRUECOLOR has map of colors, but we'll not use it. */ if ( type == TRUECOLOR ) free(image->cmap); rle_row_free( &rle_dflt_hdr, row ); } void rlecmap_to_bitmapcmap(rle, bitmap) rle_hdr *rle; bitmap_hdr *bitmap; { register int i; rle_map *rch, *gch, *bch; byte *ptr; /* Allocate memory */ ptr= bitmap->cmap= (byte *) Malloc(bitmap->colors * 3); /* * We'll use 3 ptrs, first to R channel, second to G channel, ... */ rch = rle->cmap; gch = &(rle->cmap[bitmap->colors]); bch = &(rle->cmap[2 * bitmap->colors]); for (i= 0; i< bitmap->colors; i++) { *ptr++ = (byte) (*rch++ >> 8); *ptr++ = (byte) (*gch++ >> 8); *ptr++ = (byte) (*bch++ >> 8); } } void bitmapcmap_to_rlecmap(bitmap, rle) bitmap_hdr *bitmap; rle_hdr *rle; { register int i; rle_map *rch, *gch, *bch; byte *ptr; /* Allocate memory */ rle->cmap= (rle_map *) Malloc(bitmap->colors * 3 * sizeof(rle_map)); /* * We'll use 3 ptrs, first to R channel, second to G channel, ... */ ptr = bitmap->cmap; rch = rle->cmap; gch = &(rle->cmap[bitmap->colors]); bch = &(rle->cmap[2 * bitmap->colors]); for (i= 0; i< bitmap->colors; i++) { *rch++ = (*ptr++ << 8); *gch++ = (*ptr++ << 8); *bch++ = (*ptr++ << 8); } } write_rle_file( name, image ) char *name; bitmap_hdr *image; { FILE *handle; /* Open the file descriptor */ if ( name != NULL ) handle = Fopen( name, "wb" ); else handle = stdout; /* Write the bitmap */ write_rle( handle, image ); /* Close the file */ Fclose( handle ); } write_rle(handle, image) FILE *handle; bitmap_hdr *image; { register int i, j; rle_pixel **row; byte *r, *g, *b; int offset_last; int two_lines_size; if ( image->magic != LUGUSED ) error( 19 ); VPRINTF(stderr, "Writing RLE file\n"); /* * Fill the rle header with our ( little ) information. */ rle_dflt_hdr.rle_file = handle; rle_dflt_hdr.xmin = 0; rle_dflt_hdr.ymin = 0; rle_dflt_hdr.xmax = image->xsize - 1; rle_dflt_hdr.ymax = image->ysize - 1; if (image->depth > 8) { rle_dflt_hdr.ncolors = 3; /* 24 planes */ rle_dflt_hdr.ncmap = 0; }else { rle_dflt_hdr.ncolors = 1; rle_dflt_hdr.ncmap = 3; rle_dflt_hdr.cmaplen = image->depth; /* Convert our cmap to rle cmap */ bitmapcmap_to_rlecmap(image, &rle_dflt_hdr); } rle_dflt_hdr.alpha = 0; /* we don't use alpha channels */ /* Write the header */ rle_put_setup(&rle_dflt_hdr); /* * RLE write raster lines in resverse order, so we'll put * pointers to the last line. */ offset_last = image->xsize * image->ysize - image->xsize; /* Allocate some memory */ if (rle_row_alloc(&rle_dflt_hdr, &row) < 0) error( 2 ); VPRINTF(stderr, "Compressing RLE lines\n"); if (image->depth > 8) { /* * 24 planes, rle_putrow functions use a buffer which contains * a line, so we need do it. */ /* Pointers to last line */ r = image->r + offset_last; g = image->g + offset_last; b = image->b + offset_last; two_lines_size = 2 * image->xsize; /* Write each line */ for (i= 0; i< image->ysize; i++) { for (j= 0; j< image->xsize; j++) { row[0][j] = *r++; row[1][j] = *g++; row[2][j] = *b++; } rle_putrow(row, image->xsize, &rle_dflt_hdr); /* * Now, we have pointers to the end of current line, so * we need substract two lines. */ r -= two_lines_size; g -= two_lines_size; b -= two_lines_size; } }else { /* * A image with cmap. */ r = image->r + offset_last; /* if a simple plane => stored in R componet */ for (i= 0; i< image->ysize; i++) { rle_putrow(&r, image->xsize, &rle_dflt_hdr); r -= image->xsize; } } /* * Put an EOF into the RLE file ( and THE END ! ) */ rle_puteof(&rle_dflt_hdr); rle_row_free( &rle_dflt_hdr, row ); } #endif /* iRLE */