310 lines
6.1 KiB
C
310 lines
6.1 KiB
C
/*
|
||
|
||
PNM aka "portable net map" functions.
|
||
|
||
-------------------------------------------------
|
||
|
||
14 Feb 2000: I don't know if using '-' as a filename for
|
||
means STDOUT is really a good thing ?
|
||
|
||
5 June 2001: a priori, pas de "BOUTISME" dans ces fonctions.
|
||
|
||
2 Oct 2001: voir aussi 'pov_hf15.c' pour une sauvegarde des
|
||
height_fields en PGM 15 bits.
|
||
|
||
*/
|
||
|
||
#include <stdio.h>
|
||
#include <unistd.h>
|
||
#include <string.h>
|
||
|
||
#include "../tthimage.h"
|
||
|
||
#define TAILLE_MAX_LIGNE 75
|
||
#define VERSION_STRING "December 2009"
|
||
|
||
/*::------------------------------------------------------------------::*/
|
||
/*
|
||
* this func write a bitmap from the hight bit of the
|
||
* selected channel: R, G or B.
|
||
* Parameter 'channel' is not case sensitive.
|
||
*/
|
||
int
|
||
Image_wr_pbm_0(char *nom, Image_Desc *im, char channel)
|
||
{
|
||
FILE *fp;
|
||
int x, y;
|
||
int r, g, b;
|
||
int par_ligne;
|
||
|
||
/*
|
||
* maybe we can here make a sanity check on the 'channel' par ?
|
||
*/
|
||
if ( ! strcmp("-", nom))
|
||
{
|
||
fputs("PBM go to stdout...\n", stderr);
|
||
fp = stdout;
|
||
}
|
||
else
|
||
{
|
||
#if DEBUG_LEVEL
|
||
fprintf(stderr, "create the PBM file '%s'\n", nom);
|
||
#endif
|
||
if ((fp=fopen(nom, "w")) == NULL)
|
||
{
|
||
fputs("ecriture PBM err fopen\n", stderr);
|
||
return FILE_CREATE_ERR;
|
||
}
|
||
}
|
||
|
||
fprintf(fp, "P1\n %d %d\n", im->width, im->height);
|
||
fprintf(fp, "# written by libtthimage v %s, pnm module %s\n",
|
||
IMAGE_VERSION_STRING, VERSION_STRING);
|
||
|
||
if (strlen(im->name) > 0)
|
||
{
|
||
fprintf(fp, "# image name: %s\n", im->name);
|
||
}
|
||
|
||
par_ligne = 0;
|
||
for (y=0; y<im->height; y++)
|
||
{
|
||
|
||
for (x=0; x<im->width; x++)
|
||
{
|
||
Image_getRGB(im, x, y, &r, &g, &b);
|
||
|
||
switch (channel)
|
||
{
|
||
case 'R': case 'r':
|
||
if (r & 0x80) fputs("0", fp);
|
||
else fputs("1", fp);
|
||
break;
|
||
|
||
case 'G': case 'g':
|
||
if (g & 0x80) fputs("0", fp);
|
||
else fputs("1", fp);
|
||
break;
|
||
|
||
case 'B': case 'b':
|
||
if (b & 0x80) fputs("0", fp);
|
||
else fputs("1", fp);
|
||
break;
|
||
|
||
default:
|
||
fprintf(stderr, "bad channel %c\n", channel);
|
||
break;
|
||
}
|
||
|
||
par_ligne += 1;
|
||
/*
|
||
* logic for limiting length of lines
|
||
*/
|
||
if (par_ligne > 74)
|
||
{
|
||
fputs("\n", fp);
|
||
par_ligne = 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
#if DEBUG_LEVEL
|
||
fprintf(fp, "# hello %d times, f.m.b.l folks !\n", getpid());
|
||
#endif
|
||
|
||
fputs("\n", fp);
|
||
fclose(fp);
|
||
|
||
im->modified = 0;
|
||
|
||
return FUNC_IS_BETA;
|
||
}
|
||
/*::------------------------------------------------------------------::*/
|
||
/*
|
||
* si mode == 0 alors "ascii" sinon "rawbits"
|
||
* que faire si l'image a un canal 'alpha' ?
|
||
*
|
||
* 27 Jan 2003: En fait, le nom officiel est 'Portable Pix Map',
|
||
* donc le nom de la fonction est _tr<74>s_ mal choisi.
|
||
*
|
||
*/
|
||
int
|
||
Image_wr_pnm_0(char *nom, Image_Desc *im, int mode)
|
||
{
|
||
fprintf(stderr, "*** WARNING. Use 'Image_wr_ppm_0' now !\n");
|
||
return Image_wr_ppm_0(nom, im, mode);
|
||
}
|
||
/*
|
||
* 27 Jan 2003: je renomme donc la fonction, et je cr<63>e un alias
|
||
* pour la sacro-sainte compatibilit<69> ascendante :)
|
||
*/
|
||
#define PPM_BUFSIZE 20000
|
||
int
|
||
Image_wr_ppm_0(char *nom, Image_Desc *im, int mode)
|
||
{
|
||
FILE *fp;
|
||
int par_ligne, foo, x, y, r, g, b;
|
||
#if DEBUG_LEVEL
|
||
char buffer[PPM_BUFSIZE];
|
||
#endif
|
||
|
||
#if DEBUG_LEVEL
|
||
fprintf(stderr, "ecriture image %p dans PPM %s (mode %d)\n", im, nom, mode);
|
||
#endif
|
||
|
||
if ( ! strcmp("-", nom))
|
||
{
|
||
fputs("PPM go to stdout...\n", stderr);
|
||
fp = stdout;
|
||
}
|
||
else
|
||
{
|
||
#if DEBUG_LEVEL
|
||
fprintf(stderr, "create a PPM file named '%s'\n", nom);
|
||
#endif
|
||
if ((fp=fopen(nom, "w")) == NULL)
|
||
{
|
||
fputs("ecriture PPM err fopen\n", stderr);
|
||
return FILE_CREATE_ERR;
|
||
}
|
||
/* new December 27, 2005 */
|
||
/* setbuffer(fp, buffer, PPM_BUFSIZE);*/
|
||
}
|
||
|
||
fprintf(fp, "P3\n%d %d\n255\n", im->width, im->height);
|
||
fprintf(fp, "# written by libtthimage v %s, ppm module '%s'\n\n",
|
||
IMAGE_VERSION_STRING, VERSION_STRING);
|
||
|
||
if (strlen(im->name) > 0)
|
||
{
|
||
fprintf(fp, "# image name: %s\n", im->name);
|
||
}
|
||
|
||
for (y=0; y<im->height; y++)
|
||
{
|
||
par_ligne = 0;
|
||
|
||
for (x=0; x<im->width; x++)
|
||
{
|
||
/* Image_getRGB(im, x, y, &r, &g, &b); */
|
||
r = (im->Rpix[y])[x];
|
||
g = (im->Gpix[y])[x];
|
||
b = (im->Bpix[y])[x];
|
||
foo = fprintf(fp, "%d %d %d ", r, g, b);
|
||
par_ligne += foo;
|
||
if (par_ligne > TAILLE_MAX_LIGNE)
|
||
{
|
||
fputs("\n", fp);
|
||
par_ligne = 0;
|
||
}
|
||
}
|
||
#if DEBUG_LEVEL
|
||
fprintf(fp, "# end line %d\n", y);
|
||
#else
|
||
fputs("\n", fp);
|
||
#endif
|
||
}
|
||
|
||
if (fp != stdout) fclose(fp);
|
||
|
||
im->modified = 0;
|
||
|
||
return 0;
|
||
}
|
||
/*::------------------------------------------------------------------::*/
|
||
int
|
||
Image_ppm_load_0(char *name, Image_Desc *p_ou, int reserved)
|
||
{
|
||
|
||
fprintf(stderr, "Image: charger PNM %s dans %p\n", name, p_ou);
|
||
|
||
/*
|
||
* bon, maintenant, on est au pied du mur, il faut
|
||
* parser l'en-tete.
|
||
*/
|
||
|
||
return FUNC_NOT_FINISH;
|
||
}
|
||
/*::------------------------------------------------------------------::*/
|
||
/*::------------------------------------------------------------------::*/
|
||
int
|
||
Image_wr_pgm_0(char *nom, Image_Desc *im, char channel)
|
||
{
|
||
FILE *fp;
|
||
int x, y, foo, pixel, par_ligne;
|
||
|
||
if ( ! strcmp("-", nom))
|
||
{
|
||
fputs("PGM go to stdout...\n", stderr);
|
||
fp = stdout;
|
||
}
|
||
else
|
||
{
|
||
fprintf(stderr, "create a PGM file named '%s'\n", nom);
|
||
if ((fp=fopen(nom, "w")) == NULL)
|
||
{
|
||
fputs("ecriture PGM err fopen\n", stderr);
|
||
return FILE_CREATE_ERR;
|
||
}
|
||
}
|
||
|
||
fprintf(fp, "P2\n%d %d\n255\n", im->width, im->height);
|
||
fprintf(fp, "\n# written by libtthimage v %s\n# pnm module %s\n\n",
|
||
IMAGE_VERSION_STRING, VERSION_STRING);
|
||
|
||
for (y=0; y<im->height; y++)
|
||
{
|
||
par_ligne = 0;
|
||
|
||
for (x=0; x<im->width; x++)
|
||
{
|
||
switch (channel)
|
||
{
|
||
case 'r': case 'R':
|
||
pixel = Image_R_pixel(im, x, y);
|
||
break;
|
||
case 'g': case 'G':
|
||
pixel = Image_G_pixel(im, x, y);
|
||
break;
|
||
case 'b': case 'B':
|
||
pixel = Image_B_pixel(im, x, y);
|
||
break;
|
||
default:
|
||
pixel = 42;
|
||
break;
|
||
}
|
||
|
||
foo = fprintf(fp, "%d ", pixel);
|
||
par_ligne += foo;
|
||
|
||
if (par_ligne > TAILLE_MAX_LIGNE)
|
||
{
|
||
fputs("\n", fp);
|
||
par_ligne = 0;
|
||
}
|
||
}
|
||
#if DEBUG_LEVEL
|
||
fprintf(fp, "\n# end of image line %d\n", y);
|
||
#else
|
||
fputs("\n", fp);
|
||
#endif
|
||
}
|
||
|
||
if (fp != stdout) fclose(fp);
|
||
|
||
return FUNC_IS_BETA;
|
||
}
|
||
/*::------------------------------------------------------------------::*/
|
||
/*
|
||
* oulala, il reste du travail, l<>...
|
||
*/
|
||
int
|
||
Image_pgm_alloc_load(char *nom)
|
||
{
|
||
|
||
fprintf(stderr, "Image_pgm_alloc_load(%s): pas fait...\n", nom);
|
||
|
||
return FULL_NUCKED;
|
||
}
|
||
/*::------------------------------------------------------------------::*/
|