#include <stdio.h>
#include <stdlib.h>
#include "pnm_lib.h"
#define LS_HEADER
PIXEL* read_pnm(char* ifile,PNMInfo* pi)
{
char buffer[BUFSIZ];
PIXEL* pdata;
int SizeImage;
FILE* fp=fopen(ifile,"rb");
if(fp==NULL) {
fprintf(stderr,"No such file or directory.\n");
return NULL;
}
fgets(buffer,BUFSIZ,fp);
pi->itype = atoi(buffer+1);
if(buffer[0]!='P' || pi->itype < 0 || pi->itype > 6){
fprintf(stderr,"pnm: format error\n");
return NULL;
}
pi->iw = pi->ih = 0;
while(pi->iw==0 || pi->ih==0){
fgets(buffer,BUFSIZ,fp);
if(buffer[0]!='#'){
sscanf(buffer,"%d %d",&pi->iw,&pi->ih);
}
}
if(pi->itype!=PNM_P1 && pi->itype!=PNM_P4){
pi->imax = 0;
while(pi->imax==0){
fgets(buffer,BUFSIZ,fp);
if(buffer[0] != '#'){
sscanf(buffer,"%d",&pi->imax);
}
}
}
else pi->imax = 1;
if(pi->itype==PNM_P3 || pi->itype==PNM_P6){
SizeImage=(pi->iw*pi->ih)*3;
} else {
SizeImage=(pi->iw*pi->ih);
}
#ifdef LS_HEADER
disp_header(*pi);
#endif
if(!(pdata = (PIXEL*)calloc(sizeof(PIXEL),SizeImage))){
fprintf(stderr,"cannot alloc memory..\n");
fclose(fp);
return NULL;
}
if(pi->itype==PNM_P3 || pi->itype==PNM_P6){
PNM_Cimgread(&fp,*pi,pdata);
} else {
PNM_Gimgread(&fp,*pi,pdata);
}
fclose(fp);
return pdata;
}
PIXEL* ppm2bmp(PNMInfo pi,PIXEL* pdata)
{
PIXEL* bdata;
int i,x,y,size,line,add;
line = pi.iw * 3;
if((line%4)!=0) line=((line/4)+1)*4;
add = line-pi.iw*3;
size = pi.ih * line;
bdata = (PIXEL*)calloc(size,sizeof(PIXEL));
for(y=0;y<pi.ih;y++){
for(x=0;x<pi.iw;x++){
bdata[((pi.ih-y-1)*line+x*3) + 0] = pdata[(y*pi.iw+x)*3 + 2];
bdata[((pi.ih-y-1)*line+x*3) + 1] = pdata[(y*pi.iw+x)*3 + 1];
bdata[((pi.ih-y-1)*line+x*3) + 2] = pdata[(y*pi.iw+x)*3 + 0];
}
for(i=0;i<add;i++)
bdata[((pi.ih-y-1)*line+x*3) + i] = 0;
}
return bdata;
}
PIXEL* pgm2bmp(PNMInfo pi,PIXEL* pdata)
{
PIXEL* bdata;
int i,x,y,size,line,add;
line = pi.iw;
if((line%4)!=0) line=((line/4)+1)*4;
add = line-pi.iw;
size = pi.ih * line;
bdata = (PIXEL*)calloc(size,sizeof(PIXEL));
for(y=0;y<pi.ih;y++){
for(x=0;x<pi.iw;x++)
bdata[((pi.ih-y-1)*line+x)] = pdata[y*pi.iw+x];
for(i=0;i<add;i++)
bdata[((pi.ih-y-1)*line+x)+i] = 0;
}
return bdata;
}
void disp_header(PNMInfo pi)
{
fprintf(stderr,"--------------------\n");
fprintf(stderr," image type : P%d\n",pi.itype);
fprintf(stderr," image width : %d\n",pi.iw);
fprintf(stderr,"image height : %d\n",pi.ih);
fprintf(stderr,"image bcount : %d\n",pi.imax);
fprintf(stderr,"--------------------\n");
}
void PNM_Gimgread(FILE** fp,PNMInfo pi,PIXEL* pdata)
{
int x,y,c;
PIXEL* p=pdata;
if(pi.itype == PNM_P1 || pi.itype == PNM_P2){
for(y=0;y<pi.ih;y++){
for(x=0;x<pi.iw;x++){
fscanf(*fp,"%d ",&c); *p++=(PIXEL)c;
}
}
} else {
fread(p,sizeof(PIXEL),pi.iw*pi.ih,*fp);
}
}
void PNM_Cimgread(FILE** fp,PNMInfo pi,PIXEL* pdata)
{
int x,y,c;
PIXEL* p=pdata;
if(pi.itype == PNM_P3){
for(y=0;y<pi.ih;y++){
for(x=0;x<pi.iw;x++){
fscanf(*fp,"%d ",&c); *p++=(PIXEL)c;
fscanf(*fp,"%d ",&c); *p++=(PIXEL)c;
fscanf(*fp,"%d ",&c); *p++=(PIXEL)c;
}
}
} else {
fread(p,sizeof(CPIXEL),pi.iw*pi.ih,*fp);
}
}
void write_pnm(char* ofile,PNMInfo pi,PIXEL* pdata)
{
FILE* fp=fopen(ofile,"wb+");
if(fp == NULL) return;
PNM_Headout(&fp,pi);
if(pi.itype==PNM_P3 || pi.itype==PNM_P6){
PNM_Cimgout(&fp,pi,pdata);
} else {
PNM_Gimgout(&fp,pi,pdata);
}
fclose(fp);
}
void PNM_Headout(FILE** fp,PNMInfo pi)
{
switch(pi.itype){
case PNM_P1: fprintf(*fp,"P1\n"); break;
case PNM_P2: fprintf(*fp,"P2\n"); break;
case PNM_P3: fprintf(*fp,"P3\n"); break;
case PNM_P4: fprintf(*fp,"P4\n"); break;
case PNM_P5: fprintf(*fp,"P5\n"); break;
case PNM_P6: fprintf(*fp,"P6\n"); break;
}
fprintf(*fp,"%d %d\n",pi.iw,pi.ih);
if(pi.itype != PNM_P1 && pi.itype != PNM_P4){
fprintf(*fp,"%d\n",pi.imax);
}
}
void PNM_Gimgout(FILE** fp,PNMInfo pi,PIXEL* pdata)
{
int x,y;
PIXEL* p=pdata;
if(pi.itype == PNM_P1 || pi.itype == PNM_P2){
for(y=0;y<pi.ih;y++){
for(x=0;x<pi.iw;x++){
fprintf(*fp,"%d ",*p++);
}
fprintf(*fp,"\n");
}
} else {
fwrite(p,sizeof(PIXEL),pi.iw*pi.ih,*fp);
}
}
void PNM_Cimgout(FILE** fp,PNMInfo pi,PIXEL* pdata)
{
int x,y;
PIXEL* p=pdata;
if(pi.itype == PNM_P3){
for(y=0;y<pi.ih;y++){
for(x=0;x<pi.iw;x++){
fprintf(*fp,"%d ",*p++);
fprintf(*fp,"%d ",*p++);
fprintf(*fp,"%d ",*p++);
}
fprintf(*fp,"\n");
}
} else {
fwrite(p,sizeof(CPIXEL),pi.iw*pi.ih,*fp);
}
}
void pnmSetPixel(PNMInfo pi,PIXEL* pdata,int x,int y,PIXEL p)
{
pdata[y*pi.iw+x] = p;
}
void pnmGetPixel(PNMInfo pi,PIXEL* pdata,int x,int y,PIXEL* p)
{
*p = pdata[y*pi.iw+x];
}
void pnmSetRGB(PNMInfo pi,PIXEL* pdata,int x,int y,CPIXEL p)
{
pdata[y*pi.iw*3+x*3+0] = p.r;
pdata[y*pi.iw*3+x*3+1] = p.g;
pdata[y*pi.iw*3+x*3+2] = p.b;
}
void pnmGetRGB(PNMInfo pi,PIXEL* pdata,int x,int y,CPIXEL* p)
{
p->r = pdata[y*pi.iw*3+x*3+0];
p->g = pdata[y*pi.iw*3+x*3+1];
p->b = pdata[y*pi.iw*3+x*3+2];
}