about summary refs log tree commit diff
path: root/converter/other/rast.c
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2006-08-19 03:12:28 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2006-08-19 03:12:28 +0000
commit1fd361a1ea06e44286c213ca1f814f49306fdc43 (patch)
tree64c8c96cf54d8718847339a403e5e67b922e8c3f /converter/other/rast.c
downloadnetpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.tar.gz
netpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.tar.xz
netpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.zip
Create Subversion repository
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@1 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'converter/other/rast.c')
-rw-r--r--converter/other/rast.c465
1 files changed, 465 insertions, 0 deletions
diff --git a/converter/other/rast.c b/converter/other/rast.c
new file mode 100644
index 00000000..91c50ccd
--- /dev/null
+++ b/converter/other/rast.c
@@ -0,0 +1,465 @@
+/* libpnm4.c - pnm utility library part 4
+**
+** Copyright (C) 1988 by Jef Poskanzer.
+**
+** Permission to use, copy, modify, and distribute this software and its
+** documentation for any purpose and without fee is hereby granted, provided
+** that the above copyright notice appear in all copies and that both that
+** copyright notice and this permission notice appear in supporting
+** documentation.  This software is provided "as is" without express or
+** implied warranty.
+*/
+
+#include "pnm.h"
+#include "rast.h"
+#include "mallocvar.h"
+
+/*
+** Semi-work-alike versions of some Sun pixrect routines.  Just enough
+** for rasterfile reading and writing to work.
+*/
+
+struct pixrect*
+mem_create( w, h, depth )
+    int w, h, depth;
+{
+    struct pixrect* p;
+    struct mpr_data* m;
+
+    MALLOCVAR(p);
+    if ( p == NULL )
+        return NULL;
+    p->pr_ops = NULL;
+    p->pr_size.x = w;
+    p->pr_size.y = h;
+    p->pr_depth = depth;
+    MALLOCVAR(m);
+    if ( m == NULL )
+    {
+        free( p );
+        return NULL;
+    }
+    p->pr_data = m;
+
+    /* According to the documentation, linebytes is supposed to be rounded
+    ** up to a longword (except on 386 boxes).  However, this turns out
+    ** not to be the case.  In reality, all of Sun's code rounds up to
+    ** a short, not a long.
+    */
+    m->md_linebytes = ( w * depth + 15 ) / 16 * 2;
+    m->md_offset.x = 0;
+    m->md_offset.y = 0;
+    m->md_flags = 0;
+    MALLOCARRAY(m->md_image, m->md_linebytes * h );
+    if ( m->md_image == NULL )
+    {
+        free( m );
+        free( p );
+        return NULL;
+    }
+
+    return p;
+}
+
+void
+mem_free( p )
+    struct pixrect* p;
+{
+    free( p->pr_data->md_image );
+    free( p->pr_data );
+    free( p );
+}
+
+int
+pr_dump( p, out, colormap, type, copy_flag )
+    struct pixrect* p;
+    FILE* out;
+    colormap_t* colormap;
+    int type, copy_flag;
+{
+    struct rasterfile h;
+    int size, besize, count;
+    unsigned char* beimage;
+    unsigned char* bp;
+    unsigned char c, pc;
+    int i, j;
+
+    h.ras_magic = RAS_MAGIC;
+    h.ras_width = p->pr_size.x;
+    h.ras_height = p->pr_size.y;
+    h.ras_depth = p->pr_depth;
+
+    h.ras_type = type;
+    switch ( type )
+    {
+    case RT_OLD:
+        pm_error( "This program does not know the Old rasterfile type" );
+
+    case RT_FORMAT_TIFF:
+        pm_error( "This program does not know the TIFF rasterfile type" );
+
+    case RT_FORMAT_IFF:
+        pm_error( "This program does not know the IFF rasterfile type" );
+
+    case RT_EXPERIMENTAL:
+        pm_error( "This program does not know the Experimental "
+                  "rasterfile type" );
+
+    case RT_STANDARD:
+    case RT_FORMAT_RGB:
+        /* Ignore hP->ras_length. */
+        h.ras_length = p->pr_size.y * p->pr_data->md_linebytes;
+        break;
+
+    case RT_BYTE_ENCODED:
+        size = p->pr_size.y * p->pr_data->md_linebytes;
+        bp = p->pr_data->md_image;
+        MALLOCARRAY(beimage, size * 3 / 2);  /* worst case */
+        if ( beimage == NULL )
+            return PIX_ERR;
+        besize = 0;
+        count = 0;
+        for ( i = 0; i < size; ++i )
+        {
+            c = *bp++;
+            if ( count > 0 )
+            {
+                if ( pc != c )
+                {
+                    if ( count == 1 && pc == 128 )
+                    {
+                        beimage[besize++] = 128;
+                        beimage[besize++] = 0;
+                        count = 0;
+                    }
+                    else if ( count > 2 || pc == 128 )
+                    {
+                        beimage[besize++] = 128;
+                        beimage[besize++] = count - 1;
+                        beimage[besize++] = pc;
+                        count = 0;
+                    }
+                    else
+                    {
+                        for ( j = 0; j < count; ++j )
+                            beimage[besize++] = pc;
+                        count = 0;
+                    }
+                }
+            }
+            pc = c;
+            ++count;
+            if ( count == 256 )
+            {
+                beimage[besize++] = 128;
+                beimage[besize++] = count - 1;
+                beimage[besize++] = c;
+                count = 0;
+            }
+        }
+        if ( count > 0 )
+        {
+            if ( count == 1 && c == 128 )
+            {
+                beimage[besize++] = 128;
+                beimage[besize++] = 0;
+            }
+            if ( count > 2 || c == 128 )
+            {
+                beimage[besize++] = 128;
+                beimage[besize++] = count - 1;
+                beimage[besize++] = c;
+            }
+            else
+            {
+                for ( j = 0; j < count; ++j )
+                    beimage[besize++] = c;
+            }
+        }
+        h.ras_length = besize;
+        break;
+
+    default:
+        pm_error( "unknown rasterfile type" );
+    }
+
+    if ( colormap == NULL )
+    {
+        h.ras_maptype = RMT_NONE;
+        h.ras_maplength = 0;
+    }
+    else
+    {
+        h.ras_maptype = colormap->type;
+        switch ( colormap->type )
+        {
+        case RMT_EQUAL_RGB:
+            h.ras_maplength = colormap->length * 3;
+            break;
+
+        case RMT_RAW:
+            h.ras_maplength = colormap->length;
+            break;
+
+        default:
+            pm_error( "unknown colormap type" );
+        }
+    }
+
+    if ( pm_writebiglong( out, h.ras_magic ) == -1 )
+        return PIX_ERR;
+    if ( pm_writebiglong( out, h.ras_width ) == -1 )
+        return PIX_ERR;
+    if ( pm_writebiglong( out, h.ras_height ) == -1 )
+        return PIX_ERR;
+    if ( pm_writebiglong( out, h.ras_depth ) == -1 )
+        return PIX_ERR;
+    if ( pm_writebiglong( out, h.ras_length ) == -1 )
+        return PIX_ERR;
+    if ( pm_writebiglong( out, h.ras_type ) == -1 )
+        return PIX_ERR;
+    if ( pm_writebiglong( out, h.ras_maptype ) == -1 )
+        return PIX_ERR;
+    if ( pm_writebiglong( out, h.ras_maplength ) == -1 )
+        return PIX_ERR;
+
+    if ( colormap != NULL )
+    {
+        switch ( colormap->type )
+        {
+        case RMT_EQUAL_RGB:
+            if ( fwrite( colormap->map[0], 1, colormap->length, out ) !=
+                 colormap->length )
+                return PIX_ERR;
+            if ( fwrite( colormap->map[1], 1, colormap->length, out ) !=
+                 colormap->length )
+                return PIX_ERR;
+            if ( fwrite( colormap->map[2], 1, colormap->length, out ) !=
+                 colormap->length )
+                return PIX_ERR;
+            break;
+
+        case RMT_RAW:
+            if ( fwrite( colormap->map[0], 1, colormap->length, out ) !=
+                 colormap->length )
+                return PIX_ERR;
+            break;
+        }
+    }
+
+    switch ( type )
+    {
+    case RT_STANDARD:
+    case RT_FORMAT_RGB:
+        if ( fwrite( p->pr_data->md_image, 1, h.ras_length, out ) !=
+             h.ras_length )
+            return PIX_ERR;
+        break;
+
+    case RT_BYTE_ENCODED:
+        if ( fwrite( beimage, 1, besize, out ) != besize )
+        {
+            free( beimage );
+            return PIX_ERR;
+        }
+        free( beimage );
+        break;
+    }
+
+    return 0;
+}
+
+int
+pr_load_header( in, hP )
+    FILE* in;
+    struct rasterfile* hP;
+{
+    if ( pm_readbiglong( in, &(hP->ras_magic) ) == -1 )
+        return PIX_ERR;
+    if ( hP->ras_magic != RAS_MAGIC )
+        return PIX_ERR;
+    if ( pm_readbiglong( in, &(hP->ras_width) ) == -1 )
+        return PIX_ERR;
+    if ( pm_readbiglong( in, &(hP->ras_height) ) == -1 )
+        return PIX_ERR;
+    if ( pm_readbiglong( in, &(hP->ras_depth) ) == -1 )
+        return PIX_ERR;
+    if ( pm_readbiglong( in, &(hP->ras_length) ) == -1 )
+        return PIX_ERR;
+    if ( pm_readbiglong( in, &(hP->ras_type) ) == -1 )
+        return PIX_ERR;
+    if ( pm_readbiglong( in, &(hP->ras_maptype) ) == -1 )
+        return PIX_ERR;
+    if ( pm_readbiglong( in, &(hP->ras_maplength) ) == -1 )
+        return PIX_ERR;
+    return 0;
+}
+
+int
+pr_load_colormap( in, hP, colormap )
+    FILE* in;
+    struct rasterfile* hP;
+    colormap_t* colormap;
+{
+    if ( colormap == NULL || hP->ras_maptype == RMT_NONE )
+    {
+        int i;
+
+        for ( i = 0; i < hP->ras_maplength; ++i )
+            if ( getc( in ) == EOF )
+                return PIX_ERR;
+    }
+    else
+    {
+        colormap->type = hP->ras_maptype;
+        switch ( hP->ras_maptype )
+        {
+        case RMT_EQUAL_RGB:
+            colormap->length = hP->ras_maplength / 3;
+            MALLOCARRAY( colormap->map[0], colormap->length );
+            if ( colormap->map[0] == NULL )
+                return PIX_ERR;
+            MALLOCARRAY( colormap->map[1], colormap->length );
+            if ( colormap->map[1] == NULL )
+            {
+                free( colormap->map[0] );
+                return PIX_ERR;
+            }
+            MALLOCARRAY( colormap->map[2], colormap->length );
+            if ( colormap->map[2] == NULL )
+            {
+                free( colormap->map[0] );
+                free( colormap->map[1] );
+                return PIX_ERR;
+            }
+            if ( fread( colormap->map[0], 1, colormap->length, in ) != 
+                 colormap->length ||
+                 fread( colormap->map[1], 1, colormap->length, in ) != 
+                 colormap->length ||
+                 fread( colormap->map[2], 1, colormap->length, in ) != 
+                 colormap->length )
+            {
+                free( colormap->map[0] );
+                free( colormap->map[1] );
+                free( colormap->map[2] );
+                return PIX_ERR;
+            }
+            break;
+
+        case RMT_RAW: {
+            size_t bytesRead;
+
+            colormap->length = hP->ras_maplength;
+            MALLOCARRAY( colormap->map[0], colormap->length );
+            if ( colormap->map[0] == NULL )
+                return PIX_ERR;
+            colormap->map[2] = colormap->map[1] = colormap->map[0];
+            bytesRead = fread( colormap->map[0], 1, hP->ras_maplength, in );
+            if ( bytesRead != hP->ras_maplength )
+            {
+                free( colormap->map[0] );
+                return PIX_ERR;
+            }
+        }
+            break;
+
+        default:
+            pm_error( "unknown colormap type" );
+        }
+    }
+    return 0;
+}
+
+struct pixrect*
+pr_load_image( in, hP, colormap )
+    FILE* in;
+    struct rasterfile* hP;
+    colormap_t* colormap;
+{
+    struct pixrect* p;
+    unsigned char* beimage;
+    register unsigned char* bep;
+    register unsigned char* bp;
+    register unsigned char c;
+    int i;
+    register int j, count;
+
+    p = mem_create( hP->ras_width, hP->ras_height, hP->ras_depth );
+    if ( p == NULL )
+        return NULL;
+
+    switch ( hP->ras_type )
+    {
+    case RT_OLD:
+        pm_error( "This program does not know the Old rasterfile type" );
+
+    case RT_FORMAT_TIFF:
+        pm_error( "This program does not know the TIFF rasterfile type" );
+
+    case RT_FORMAT_IFF:
+        pm_error( "This program does not know the IFF rasterfile type" );
+
+    case RT_EXPERIMENTAL:
+        pm_error( "This program does not know the Experimental "
+                  "rasterfile type" );
+
+    case RT_STANDARD:
+    case RT_FORMAT_RGB:
+        /* Ignore hP->ras_length. */
+        i = p->pr_size.y * p->pr_data->md_linebytes;
+        if ( fread( p->pr_data->md_image, 1, i, in ) != i )
+        {
+            mem_free( p );
+            return NULL;
+        }
+        break;
+
+    case RT_BYTE_ENCODED:
+        MALLOCARRAY( beimage, hP->ras_length );
+        if ( beimage == NULL )
+        {
+            mem_free( p );
+            return NULL;
+        }
+        if ( fread( beimage, 1, hP->ras_length, in ) != hP->ras_length )
+        {
+            mem_free( p );
+            free( beimage );
+            return NULL;
+        }
+        bep = beimage;
+        bp = p->pr_data->md_image;
+        for ( i = 0; i < hP->ras_length; )
+        {
+            c = *bep++;
+            if ( c == 128 )
+            {
+                count = ( *bep++ ) + 1;
+                if ( count == 1 )
+                {
+                    *bp++ = 128;
+                    i += 2;
+                }
+                else
+                {
+                    c = *bep++;
+                    for ( j = 0; j < count; ++j )
+                        *bp++ = c;
+                    i += 3;
+                }
+            }
+            else
+            {
+                *bp++ = c;
+                ++i;
+            }
+        }
+        free( beimage );
+        break;
+
+    default:
+        pm_error( "unknown rasterfile type" );
+    }
+
+    return p;
+}