Category : OS/2 Files
Archive   : PBMPLUS4.ZIP
Filename : LIBPPM3.C

 
Output of file : LIBPPM3.C contained in archive : PBMPLUS4.ZIP
/* libppm3.c - ppm utility library part 3
**
** Colormap routines.
**
** Copyright (C) 1989, 1991 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 "ppm.h"
#include "ppmcmap.h"
#include "libppm.h"

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

#define HASH_SIZE 20023

#ifdef PPM_PACKCOLORS
#define ppm_hashpixel(p) ( ( (int) (p) & 0x7fffffff ) % HASH_SIZE )
#else /*PPM_PACKCOLORS*/
#define ppm_hashpixel(p) ( ( ( (long) PPM_GETR(p) * 33023 + (long) PPM_GETG(p) * 30013 + (long) PPM_GETB(p) * 27011 ) & 0x7fffffff ) % HASH_SIZE )
#endif /*PPM_PACKCOLORS*/

colorhist_vector
ppm_computecolorhist( pixels, cols, rows, maxcolors, colorsP )
pixel** pixels;
int cols, rows, maxcolors;
int* colorsP;
{
colorhash_table cht;
colorhist_vector chv;

cht = ppm_computecolorhash( pixels, cols, rows, maxcolors, colorsP );
if ( cht == (colorhash_table) 0 )
return (colorhist_vector) 0;
chv = ppm_colorhashtocolorhist( cht, maxcolors );
ppm_freecolorhash( cht );
return chv;
}

void
ppm_addtocolorhist( chv, colorsP, maxcolors, colorP, value, position )
colorhist_vector chv;
pixel* colorP;
int* colorsP;
int maxcolors, value, position;
{
int i, j;

/* Search colorhist for the color. */
for ( i = 0; i < *colorsP; ++i )
if ( PPM_EQUAL( chv[i].color, *colorP ) )
{
/* Found it - move to new slot. */
if ( position > i )
{
for ( j = i; j < position; ++j )
chv[j] = chv[j + 1];
}
else if ( position < i )
{
for ( j = i; j > position; --j )
chv[j] = chv[j - 1];
}
chv[position].color = *colorP;
chv[position].value = value;
return;
}
if ( *colorsP < maxcolors )
{
/* Didn't find it, but there's room to add it; so do so. */
for ( i = *colorsP; i > position; --i )
chv[i] = chv[i - 1];
chv[position].color = *colorP;
chv[position].value = value;
++(*colorsP);
}
}

colorhash_table
ppm_computecolorhash( pixels, cols, rows, maxcolors, colorsP )
pixel** pixels;
int cols, rows, maxcolors;
int* colorsP;
{
colorhash_table cht;
register pixel* pP;
colorhist_list chl;
int col, row, hash;

cht = ppm_alloccolorhash( );
*colorsP = 0;

/* Go through the entire image, building a hash table of colors. */
for ( row = 0; row < rows; ++row )
for ( col = 0, pP = pixels[row]; col < cols; ++col, ++pP )
{
hash = ppm_hashpixel( *pP );
for ( chl = cht[hash]; chl != (colorhist_list) 0; chl = chl->next )
if ( PPM_EQUAL( chl->ch.color, *pP ) )
break;
if ( chl != (colorhist_list) 0 )
++(chl->ch.value);
else
{
if ( ++(*colorsP) > maxcolors )
{
ppm_freecolorhash( cht );
return (colorhash_table) 0;
}
#ifdef MALLOC_WORKS_NOW
chl = (colorhist_list) malloc( sizeof(struct colorhist_list_item) );
#else
if (DosAllocMem ((PPVOID) & chl, sizeof (struct colorhist_list_item),
fALLOC))
chl = (colorhist_list) 0;
#endif
if ( chl == (colorhist_list) 0 )
pm_error( "out of memory computing hash table" );
chl->ch.color = *pP;
chl->ch.value = 1;
chl->next = cht[hash];
cht[hash] = chl;
}
}

return cht;
}

colorhash_table
ppm_alloccolorhash( )
{
colorhash_table cht;
int i;

#ifdef MALLOC_WORKS_NOW
cht = (colorhash_table) malloc( HASH_SIZE * sizeof(colorhist_list) );
#else
if (DosAllocMem ((PPVOID) & cht, HASH_SIZE * sizeof (colorhist_list),
fALLOC))
cht = (colorhash_table) 0;
#endif
if ( cht == (colorhash_table) 0 )
pm_error( "out of memory allocating hash table" );

for ( i = 0; i < HASH_SIZE; ++i )
cht[i] = (colorhist_list) 0;

return cht;
}

int
ppm_addtocolorhash( cht, colorP, value )
colorhash_table cht;
pixel* colorP;
int value;
{
register int hash;
#ifdef MALLOC_WORKS_NOW
register colorhist_list chl;

chl = (colorhist_list) malloc( sizeof(struct colorhist_list_item) );
#else
colorhist_list chl;

if (DosAllocMem ((PPVOID) & chl, sizeof (struct colorhist_list_item),
fALLOC))
chl = (colorhist_list) 0;
#endif
if ( chl == (colorhist_list) 0 )
return -1;
hash = ppm_hashpixel( *colorP );
chl->ch.color = *colorP;
chl->ch.value = value;
chl->next = cht[hash];
cht[hash] = chl;
return 0;
}

colorhist_vector
ppm_colorhashtocolorhist( cht, maxcolors )
colorhash_table cht;
int maxcolors;
{
colorhist_vector chv;
colorhist_list chl;
int i, j;

/* Now collate the hash table into a simple colorhist array. */
#ifdef MALLOC_WORKS_NOW
chv = (colorhist_vector) malloc( maxcolors * sizeof(struct colorhist_item) );
#else
if (DosAllocMem ((PPVOID) & chv, maxcolors * sizeof (struct colorhist_item),
fALLOC))
chv = (colorhist_vector) 0;
#endif
/* (Leave room for expansion by caller.) */
if ( chv == (colorhist_vector) 0 )
pm_error( "out of memory generating histogram" );

/* Loop through the hash table. */
j = 0;
for ( i = 0; i < HASH_SIZE; ++i )
for ( chl = cht[i]; chl != (colorhist_list) 0; chl = chl->next )
{
/* Add the new entry. */
chv[j] = chl->ch;
++j;
}

/* All done. */
return chv;
}

colorhash_table
ppm_colorhisttocolorhash( chv, colors )
colorhist_vector chv;
int colors;
{
colorhash_table cht;
int i, hash;
pixel color;
colorhist_list chl;

cht = ppm_alloccolorhash( );

for ( i = 0; i < colors; ++i )
{
color = chv[i].color;
hash = ppm_hashpixel( color );
for ( chl = cht[hash]; chl != (colorhist_list) 0; chl = chl->next )
if ( PPM_EQUAL( chl->ch.color, color ) )
pm_error(
"same color found twice - %d %d %d", PPM_GETR(color),
PPM_GETG(color), PPM_GETB(color) );
#ifdef MALLOC_WORKS_NOW
chl = (colorhist_list) malloc( sizeof(struct colorhist_list_item) );
#else
if (DosAllocMem ((PPVOID) & chl, sizeof (struct colorhist_list_item),
fALLOC))
chl = (colorhist_list) 0;
#endif
if ( chl == (colorhist_list) 0 )
pm_error( "out of memory" );
chl->ch.color = color;
chl->ch.value = i;
chl->next = cht[hash];
cht[hash] = chl;
}

return cht;
}

int
ppm_lookupcolor( cht, colorP )
colorhash_table cht;
pixel* colorP;
{
int hash;
colorhist_list chl;

hash = ppm_hashpixel( *colorP );
for ( chl = cht[hash]; chl != (colorhist_list) 0; chl = chl->next )
if ( PPM_EQUAL( chl->ch.color, *colorP ) )
return chl->ch.value;

return -1;
}

void
ppm_freecolorhist( chv )
colorhist_vector chv;
{
#ifdef MALLOC_WORKS_NOW
free( (char*) chv );
#else
DosFreeMem (chv);
#endif
}

void
ppm_freecolorhash( cht )
colorhash_table cht;
{
int i;
colorhist_list chl, chlnext;

for ( i = 0; i < HASH_SIZE; ++i )
for ( chl = cht[i]; chl != (colorhist_list) 0; chl = chlnext )
{
chlnext = chl->next;
#ifdef MALLOC_WORKS_NOW
free( (char*) chl );
#else
DosFreeMem (chl);
#endif
}
#ifdef MALLOC_WORKS_NOW
free( (char*) cht );
#else
DosFreeMem (cht);
#endif
}


  3 Responses to “Category : OS/2 Files
Archive   : PBMPLUS4.ZIP
Filename : LIBPPM3.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/