Category : OS/2 Files
Archive   : PBMPLUS3.ZIP
Filename : LIBPNM4.C

 
Output of file : LIBPNM4.C contained in archive : PBMPLUS3.ZIP
/* 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"

#ifndef MALLOC_WORKS_NOW
#define INCL_NOPMAPI
#define INCL_DOSMEMMGR
#include
#endif

/*
** 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;

#ifdef MALLOC_WORKS_NOW
p = (struct pixrect*) malloc( sizeof(struct pixrect) );
#else
if (DosAllocMem ((PPVOID) & p, sizeof (struct pixrect), fALLOC))
p = NULL;
#endif
if ( p == NULL )
return NULL;
p->pr_ops = NULL;
p->pr_size.x = w;
p->pr_size.y = h;
p->pr_depth = depth;
#ifdef MALLOC_WORKS_NOW
m = p->pr_data = (struct mpr_data*) malloc( sizeof(struct mpr_data) );
#else
if (DosAllocMem ((PPVOID) & m, sizeof (struct mpr_data), fALLOC))
m = NULL;
#endif
if ( m == NULL )
{
#ifdef MALLOC_WORKS_NOW
free( p );
#else
DosFreeMem (p);
#endif
return NULL;
}
/* 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;
#ifdef MALLOC_WORKS_NOW
m->md_image = (unsigned char*) malloc( m->md_linebytes * h );
#else
if (DosAllocMem ((PPVOID) & m->md_image, m->md_linebytes * h, fALLOC))
m->md_image = NULL;
#endif
if ( m->md_image == NULL )
{
#ifdef MALLOC_WORKS_NOW
free( m );
free( p );
#else
DosFreeMem (m);
DosFreeMem (p);
#endif
return NULL;
}

return p;
}

void
mem_free( p )
struct pixrect* p;
{
#ifdef MALLOC_WORKS_NOW
free( p->pr_data->md_image );
free( p->pr_data );
free( p );
#else
DosFreeMem (p->pr_data->md_image);
DosFreeMem (p->pr_data);
DosFreeMem (p);
#endif
}

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( "old rasterfile type is not supported" );

case RT_FORMAT_TIFF:
pm_error( "tiff rasterfile type is not supported" );

case RT_FORMAT_IFF:
pm_error( "iff rasterfile type is not supported" );

case RT_EXPERIMENTAL:
pm_error( "experimental rasterfile type is not supported" );

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;
#ifdef MALLOC_WORKS_NOW
beimage = (unsigned char*) malloc( size * 3 / 2 ); /* worst case */
#else
if (DosAllocMem ((PPVOID) & beimage, size * 3 / 2, fALLOC))
beimage = NULL;
#endif
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 )
{
#ifdef MALLOC_WORKS_NOW
free( beimage );
#else
DosFreeMem (beimage);
#endif
return PIX_ERR;
}
#ifdef MALLOC_WORKS_NOW
free( beimage );
#else
DosFreeMem (beimage);
#endif
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;
#ifdef MALLOC_WORKS_NOW
colormap->map[0] = (unsigned char*) malloc( colormap->length );
#else
if (DosAllocMem ((PPVOID) & colormap->map[0], colormap->length, fALLOC))
colormap->map[0] = NULL;
#endif
if ( colormap->map[0] == NULL )
return PIX_ERR;
#ifdef MALLOC_WORKS_NOW
colormap->map[1] = (unsigned char*) malloc( colormap->length );
#else
if (DosAllocMem ((PPVOID) & colormap->map[1], colormap->length, fALLOC))
colormap->map[1] = NULL;
#endif
if ( colormap->map[1] == NULL )
{
#ifdef MALLOC_WORKS_NOW
free( colormap->map[0] );
#else
DosFreeMem (colormap->map [0]);
#endif
return PIX_ERR;
}
#ifdef MALLOC_WORKS_NOW
colormap->map[2] = (unsigned char*) malloc( colormap->length );
#else
if (DosAllocMem ((PPVOID) & colormap->map[2], colormap->length, fALLOC))
colormap->map[2] = NULL;
#endif
if ( colormap->map[2] == NULL )
{
#ifdef MALLOC_WORKS_NOW
free( colormap->map[0] );
free( colormap->map[1] );
#else
DosFreeMem (colormap->map [0]);
DosFreeMem (colormap->map [1]);
#endif
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 )
{
#ifdef MALLOC_WORKS_NOW
free( colormap->map[0] );
free( colormap->map[1] );
free( colormap->map[2] );
#else
DosFreeMem (colormap->map [0]);
DosFreeMem (colormap->map [1]);
DosFreeMem (colormap->map [2]);
#endif
return PIX_ERR;
}
break;

case RMT_RAW:
colormap->length = hP->ras_maplength;
#ifdef MALLOC_WORKS_NOW
colormap->map[0] = (unsigned char*) malloc( colormap->length );
#else
if (DosAllocMem ((PPVOID) & colormap->map[0], colormap->length, fALLOC))
colormap->map[0] = NULL;
#endif
if ( colormap->map[0] == NULL )
return PIX_ERR;
colormap->map[2] = colormap->map[1] = colormap->map[0];
if ( fread( colormap->map[0], 1, hP->ras_maplength, in ) != hP->ras_maplength )
{
#ifdef MALLOC_WORKS_NOW
free( colormap->map[0] );
#else
DosFreeMem (colormap->map [0]);
#endif
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( "old rasterfile type is not supported" );

case RT_FORMAT_TIFF:
pm_error( "tiff rasterfile type is not supported" );

case RT_FORMAT_IFF:
pm_error( "iff rasterfile type is not supported" );

case RT_EXPERIMENTAL:
pm_error( "experimental rasterfile type is not supported" );

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:
#ifdef MALLOC_WORKS_NOW
beimage = (unsigned char*) malloc( hP->ras_length );
#else
if (DosAllocMem ((PPVOID) & beimage, hP->ras_length, fALLOC))
beimage = NULL;
#endif
if ( beimage == NULL )
{
mem_free( p );
return NULL;
}
if ( fread( beimage, 1, hP->ras_length, in ) != hP->ras_length )
{
mem_free( p );
#ifdef MALLOC_WORKS_NOW
free( beimage );
#else
DosFreeMem (beimage);
#endif
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;
}
}
#ifdef MALLOC_WORKS_NOW
free( beimage );
#else
DosFreeMem (beimage);
#endif
break;

default:
pm_error( "unknown rasterfile type" );
}

return p;
}


  3 Responses to “Category : OS/2 Files
Archive   : PBMPLUS3.ZIP
Filename : LIBPNM4.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/