/* Herewith the glue between fig2pdf and bmp2eps code */

#include<stdio.h>
#include<stdlib.h>  /* exit() */
#include<stdarg.h>
#include<string.h>

#include "fig2pdf.h"

#include "bmp2eps.h"

extern struct img_obj images;

int read_image(struct bitmap *image, FILE *infile,
               int user_trans, unsigned int ctrans[3]);
unsigned int A85p(FILE *out, unsigned char *in, int len);
void readpdf(char *file1,double llx,double lly,
	    double width,double height,double angle,int depth,int fl);
void readeps(char *file1,double llx,double lly,
	    double width,double height,double angle,int depth,int fl);

void write_picture(char *file1,double llx,double lly,
		   double width,double height,int depth,int fl){
  int user_trans=0,i,nimage,dict,compress,binary,debug;
  unsigned int ctrans[3],len;
  int smooth=0,pdf_image_type,flipped,old=-1;
  char buffer[1000];

  FILE *infile,*out;
  struct bitmap *image;
  struct img_obj *img;

  i=strlen(file1);
  if ((i>4)&&(strcmp(".pdf",file1+i-4)==0)){
    readpdf(file1,llx,lly,width,height,0.0,depth,fl);
    return;
  }

  if ((i>4)&&(strcmp(".eps",file1+i-4)==0)){
    readeps(file1,llx,lly,width,height,0.0,depth,fl);
    return;
  }

  debug=flags&DEBUG_MASK;
  image=malloc(sizeof(struct bitmap));
  image->trans=NULL;
  image->dpi_x=image->dpi_y=0;
  image->flags=flags;
  compress=-1;
  ctrans[0]=ctrans[1]=ctrans[2]=255;
  out=pdf;

  binary=flags&BINARY;
  image->compression=0;
#ifdef USE_LZW
  image->compression=LZW;
#endif
#ifdef USE_ZLIB
  image->compression=FLATE;
#endif

  nimage=0;
  img=&images;
  if ((img->filename)&&(strcmp(img->filename,file1)==0)) old=0;
  if (img->dict) nimage=1;
  while (img->next){
    img=img->next;
    if ((img->filename)&&(strcmp(img->filename,file1)==0)) old=nimage;
    nimage++;
  }

  infile=NULL;
  infile=fopen(file1,"rb");
  if(!infile){
    fprintf(stderr,"Error, unable to open %s for reading.\n",file1);
    exit(1);
  }

  flipped=fl;
  if (old!=-1) {
    nimage=old;
    if (debug) fprintf(stderr,"Reusing Img%d for %s\n",old,file1);
  }

  if (((flipped==0)&&(width*height>0))||
      ((flipped==1)&&(width*height<0)))
    i=sprintf(buffer,"q\n"
	      "%.2f 0 0 %.2f %.2f %.2f cm\n"
	      "/Img%d Do\n"
	      "Q",
	      width,height,llx,lly,nimage);
  else
    i=sprintf(buffer,"q\n"
	      "0 %.2f %.2f 0 %.2f %.2f cm\n"
	      "/Img%d Do\n"
	      "Q",
	      height,width,llx,lly,nimage);

  OBJ_PRN("<</Length %d>> stream\n%s\nendstream\nendobj\n\n",i,buffer);
  add_obj(cref,depth);

  if (old!=-1) return;

  read_image(image,infile,user_trans,ctrans);

  if (image->compression==DCT) smooth=1;

  pdf_image_type='C';
  if (image->colour==GREY)  pdf_image_type='B';
  if (image->type==PALETTE) pdf_image_type='I';


  OBJ_PRN("<</Type /XObject\n"
          "/Subtype /Image\n/Width %d /Height %d\n"
          "/BitsPerComponent %d\n"
          "/ColorSpace ",
          image->width,image->height,
          (image->colour==RGB)?image->depth/3:image->depth);
  dict=cref;

  if (pdf_image_type=='B')
    xref[cref]+=fprintf(out,"/DeviceGray\n");
  else if (pdf_image_type=='C')
    xref[cref]+=fprintf(out,"/DeviceRGB\n");
  else
    xref[cref]+=fprintf(out,"[/Indexed /DeviceRGB %d %d 0 R]\n",
                       image->pal_len-1,cref+((binary)?1:2));
  if (image->trans){
    xref[cref]+=fprintf(out,"/Mask [");
    if (image->colour==RGB) xref[cref]+=fprintf(out,"%d %d %d %d %d %d]\n",
                                                      (int)image->trans[0],
                                                      (int)image->trans[0],
                                                      (int)image->trans[1],
                                                      (int)image->trans[1],
                                                      (int)image->trans[2],
                                                      (int)image->trans[2]);
    else xref[cref]+=fprintf(out,"%d %d]\n",(int)(*image->trans),
                                            (int)(*image->trans));
  }
  if (smooth) xref[cref]+=fprintf(out,"/Interpolate true\n");
  xref[cref]=xref[cref]+fprintf(out,"/Filter [");
  if (!binary) xref[cref]=xref[cref]+fprintf(out,"/ASCII85Decode");

  if (image->compression==DCT)
    xref[cref]+=fprintf(out," /DCTDecode]");
  else if ((image->compression==FLATE)||(image->compression=LZW)){
    if (image->compression==FLATE)
      xref[cref]+=fprintf(out," /FlateDecode]\n");
    else
      xref[cref]+=fprintf(out," /LZWDecode]\n");
    if (image->flags&PREDICT) {
      xref[cref]+=fprintf(out,"/DecodeParms [%s\n"
                          "<</Predictor 10 "
                          "/Columns %d /Colors %d "
                          "/BitsPerComponent %d>>\n]",
                          (binary)?"":"null ",
                          image->width,
                          (image->colour==RGB)?3:1,
                          (image->colour==RGB)?image->depth/3:
                          image->depth);
    }
  }
  else if (image->compression==0)
    xref[cref]+=fprintf(out,"]");
  else{
    fprintf(stderr,"Unexpected compression type %d in write_picture\n",
            image->compression);
    exit(1);
  }

  if (binary){
    xref[cref]=xref[cref]+fprintf(out,"\n"
                                 "/Length %d\n"
                                 ">> stream\n",image->data_len);
    len=fwrite(image->data,1,image->data_len,out);
  }
  else{
    xref[cref]=xref[cref]+fprintf(out,"\n"
                                 "/Length %d 0 R\n"
                                 ">> stream\n",cref+1);
    len=A85p(out,image->data,image->data_len);
  }

  xref[cref]=xref[cref]+len+fprintf(out,"endstream\nendobj\n\n");

  if (!binary) {OBJ_PRN("%d\nendobj\n\n",len);}

  if (pdf_image_type=='I'){
    if (binary){
      OBJ_PRN("<</Length %d\n>>\nstream\n",3*image->pal_len);
      xref[cref]+=fwrite(image->palette,1,3*image->pal_len,out);
      xref[cref]+=fprintf(out,"\nendstream\nendobj\n\n");
    }
    else{
      OBJ_PRN("<</Filter /ASCII85Decode /Length %d 0 R>>\nstream\n",
              cref+1);
      len=A85p(out,image->palette,3*image->pal_len);
      xref[cref]+=len+fprintf(out,"endstream\nendobj\n\n");
      OBJ_PRN("%d\nendobj\n\n",len);
    }
  }

  if (img->dict!=0){
    img->next=malloc(sizeof(struct img_obj));
    if (!img->next){
      fprintf(stderr,"Malloc error in write_picture\n");
      exit(1);
    }
    img=img->next;
  }

  img->dict=dict;
  img->next=NULL;
  img->filename=malloc(strlen(file1)+1);
    if (!img->filename){
      fprintf(stderr,"Malloc error in write_picture\n");
      exit(1);
    }
  strcpy(img->filename,file1);

}
