/* ppmtoxvmini - convert PPM to `xvpic', and generate PPM 3:3:2 map.
 * PD by RJM
 */

#include <stdio.h>
#include <string.h>

#ifdef KANDR
#define void int
#endif


unsigned char input[80*60*3],output[80*60];
int map[256*3];


/* output 3:3:2 palette as PPM */
void writemap()
{
int f;

printf("P6\n256 1\n255\n");
for(f=0;f<256;f++)
  printf("%c%c%c",map[f*3],map[f*3+1],map[f*3+2]);
}


void educate_luser()
{
/* revolting for maximum portability :-/ */
fprintf(stderr,
"\nppmtoxvmini is a simple mapped-PPM-to-xvpic program which relies on\n");
fprintf(stderr,
"other programs to do the hard work. Here's an example use of ppmtoxvmini:\n");
fprintf(stderr,
"\nppmtoxvmini -genmap >map\n");
fprintf(stderr,
"djpeg -fast foo.jpg | pnmscale -xysize 80 60 | ppmquant -fs -map map | \\\n");
fprintf(stderr,
"\tppmtoxvmini >.xvpics/foo.jpg\n\n");
fprintf(stderr,
"However, ppmtoxvmini is not really designed to be used directly; you're\n");
fprintf(stderr,
"probably better off using `makexvpics'.\n");

exit(1);
}


#ifdef KANDR
main(argc,argv)
int argc;
char *argv[];
#else
int main(int argc,char *argv[])
#endif
{
FILE *in=stdin;
unsigned char *ptr;
char buf[128];
int x,y,f,w,h,r,g,b,tmp,*iptr;

/* generate 332 map */
iptr=map;
for(r=0;r<8;r++)
  for(g=0;g<8;g++)
    for(b=0;b<4;b++)
      {
      *iptr++=r*255/7;
      *iptr++=g*255/7;
      *iptr++=b*255/3;
      }

if(argc==2 && strcmp(argv[1],"-genmap")==0)
  writemap(),exit(0);

if(argc==2)
  if((in=fopen(argv[1],"rb"))==NULL)
    fprintf(stderr,"ppmtoxvmini: couldn't open input file.\n"),exit(1);

if(in!=stdin) fclose(in);

fgets(buf,sizeof(buf),in);
if(strcmp(buf,"P6\n")!=0)
  fprintf(stderr,"ppmtoxvmini: not a raw PPM file.\n"),exit(1);

do fgets(buf,sizeof(buf),in); while(buf[0]=='#');

if(sscanf(buf,"%d%d",&w,&h)!=2)
  fprintf(stderr,"ppmtoxvmini: not a raw PPM file.\n"),exit(1);
if(w>80 || h>60)
  fprintf(stderr,"ppmtoxvmini: input file bigger than 80x60.\n"),
  educate_luser();

do fgets(buf,sizeof(buf),in); while(buf[0]=='#');

if(sscanf(buf,"%d",&tmp)!=1)
  fprintf(stderr,"ppmtoxvmini: not a raw PPM file.\n"),exit(1);
if(tmp!=255)
  fprintf(stderr,"ppmtoxvmini: maxval must be 255 - try `pnmdepth 255'.\n"),
  exit(1);

if(fread(input,1,w*h*3,in)!=w*h*3)
  fprintf(stderr,"ppmtoxvmini: couldn't read input.\n"),exit(1);

ptr=input;
for(y=0;y<h;y++)
  for(x=0;x<w;x++)
    {
    r=*ptr++; g=*ptr++; b=*ptr++;
    for(f=0;f<256*3;f+=3)
      if(map[f]==r && map[f+1]==g && map[f+2]==b)
        break;
    if(f==256*3)
      fprintf(stderr,
      "ppmtoxvmini: input must match map output by `ppmtoxvmini -genmap'.\n"),
      educate_luser();
    
    output[y*w+x]=f/3;
    }

printf("P7 332\n");
printf("# xv-compatible thumbnail from ppmtoxvmini\n");
printf("#END_OF_COMMENTS\n");
printf("%d %d 255\n",w,h);

for(y=0;y<h;y++)
  if(fwrite(output+y*w,1,w,stdout)!=w)
    fprintf(stderr,"ppmtoxvmini: couldn't write output.\n"),exit(1);

exit(0);
}
