/*************************************************************
*                      dump2880.C                            *
*                 Auteur: GRIMBERT Jrme                    *
*                      version 3.2                           *
*                     rev. 29/09/94                          *
* Convertit les images DKB (rgb) en un fichier pour          *
* une imprimante couleurs.                                   *
* L'imprimante est une Canon BJC600 en mode LQ.              *
* Rsolution : 360 x 360 dpi                                 *
* largeur image : 2880 points maxi                           *
* Matrice de mlange pour obtenir la couleur : 1x1           *
* Adressage en mode 48 bits                                  *
* Nombre de couleurs utilises : 4 (CMYK)                    *
*                                                            *
* - utilisation du noir pur au lieu du noir composite        *
*   pour essayer de restituer des gris corrects              *
* - abandon des trames prdfinies pour la gnration des    *
*   couleurs  (gnration dynamique)                         *
* - 4 passages d'encres au lieu de 3 -> segmentation de      *
*   l'image pour rester dans les 60Ko du buffer (esthetique) *
* Modification par rapport  la version 1.0                  *
* - changement de nom (rgb2paper)                            *
* Modification par rapport  la version 2.0                  *
* - mise  blanc correcte de la marge infrieure de l'image  *
* Modification par rapport  la version 3.0                  *
* - optimisation de l'algorithme de remplissage de grille    *
* Modification par rapport  la version 3.1                  *
* - Flush des sorties (en cas de redirection)                *
*************************************************************/

#include <stdio.h>
#include <stdlib.h>

#ifdef QDOS
#include <qdos.h>
#include <string.h>
#define BAD -1
#define USAGE "Usage: EX %s;\"input_file output_file\"\n"
#define INIT
long _stack=32768L;
#else
#define BAD 1
#define USAGE "Usage: %s input_file output_file\n"
#define INIT
#endif

/* Version du programme */

char _version[] = "v3.2";

/* Nom du programme */

char _prog_name[] = "dump2880";

/* Variables globales et routine d'initialisation spcifiques au QDOS */

#ifdef QDOS

char _copyright[] = "Grimbert Jrme";
char *_endmsg     = "Press Any Valid Key"; /* Let me read the screen */

/* Dimensions de la fentre */

struct WINDOWDEF _condetails = { 208, 1, 0, 7, 448, 200, 32, 16};
struct QLRECT    rect        = { 448, 186, 32, 30 };

/* excution de la routine d'ouverture de la fentre par dfaut */

char _conname[]              = "con_448x200a32x16";
void (*_consetup)()          = consetup_title;




#endif

#define REVERSE(a) ((a>>8)+((a&0xFF)<<8))

void end_page(fich)
FILE *fich;
{
unsigned char c=12; /* this is Form Feed code */
fwrite(&c,1,1,fich);
}

void generate(in,largeur,fich)
char *in;
unsigned short largeur;
FILE * fich;
{
/* the last 0 are here just in case you change for something like printf */
static char colorseparator[]={13,0};
static char nextline[]={27,'J',24,0};
static char black[]={27,'r',0,0};
static char cyan[]={27,'r',2,0};
static char magenta[]={27,'r',1,0};
static char yellow[]={27,'r',4,0};
static char graphic[]={27,'*',72,0};
static char leftmargin[]={27,'$',0,0,0};
static char middlemargin[]={27,'$',240,0,0}; /* middle of page, if in 1/60" */
unsigned short k,l,m;
unsigned char octet,r,*q;
int val,i,j,line,n;
l=k=(m=largeur); /* nombre de points horizontaux */
if (k>1440) {k=1440; m=1440;} /* decoupage ncessaire pour les 60K du buffer */
k=REVERSE(k); /* LSB first */
#define middle_page 1440

/* first go to the left margin */
fwrite(leftmargin,4,1,fich);
fwrite(black,3,1,fich);
fwrite(graphic,3,1,fich);
fwrite(&k,2,1,fich);
/* we have now to send 6 * m bytes to define the black (48) lines */
 /* in [couleur][xpos][ypos]   {0..3}{0..l-1}{0..5} */
 /* */
 fwrite(in,6*m,1,fich); /* memory is linear, no? HHOS */

fwrite(colorseparator,1,1,fich); /* CR doesn't print in graphic mode */
/* back to the start of the line */
fwrite(cyan,3,1,fich);
fwrite(graphic,3,1,fich);
fwrite(&k,2,1,fich);
/* we have now to send 6 * m bytes to define the cyan (48) lines */
 fwrite(in+l*6,6*m,1,fich);

fwrite(colorseparator,1,1,fich); /* CR doesn't print in graphic mode */
fwrite(magenta,3,1,fich);
fwrite(graphic,3,1,fich);
fwrite(&k,2,1,fich);
/* again, 6 * largeur bytes to define magenta (48) lines */
 fwrite(in+l*6*2,6*m,1,fich);

fwrite(colorseparator,1,1,fich); /* CR doesn't print in graphic mode */
fwrite(yellow,3,1,fich);
fwrite(graphic,3,1,fich);
fwrite(&k,2,1,fich);
/* and last, 6 * largeur bytes for the 48 lines of yellow */
 fwrite(in+l*6*3,6*m,1,fich);

if (m!=largeur) /* we have cut the output to avoid printer buffer saturation */
{ /* print the rest of the picture */
m=largeur-m;
k=m;
k=REVERSE(k);
fwrite(middlemargin,4,1,fich);
fwrite(black,3,1,fich);
fwrite(graphic,3,1,fich);
fwrite(&k,2,1,fich);
/* we have now to send 6 * m bytes to define the black (48) lines */
 /* in [couleur][xpos][ypos]   {0..3}{0..l-1}{0..5} */
 /* */
 fwrite(in+middle_page*6,6*m,1,fich); /* memory is linear, no? HHOS!! */

fwrite(middlemargin,4,1,fich); /*  */

fwrite(cyan,3,1,fich);
fwrite(graphic,3,1,fich);
fwrite(&k,2,1,fich);
/* we have now to send 6 * m bytes to define the cyan (48) lines */
 fwrite(in+l*6+middle_page*6,6*m,1,fich);

fwrite(middlemargin,4,1,fich); /* */
fwrite(magenta,3,1,fich);
fwrite(graphic,3,1,fich);
fwrite(&k,2,1,fich);
/* again, 6 * largeur bytes to define magenta (48) lines */
 fwrite(in+l*6*2+middle_page*6,6*m,1,fich);

fwrite(middlemargin,4,1,fich); /* */
fwrite(yellow,3,1,fich);
fwrite(graphic,3,1,fich);
fwrite(&k,2,1,fich);
/* and last, 6 * largeur bytes for the 48 lines of yellow */
 fwrite(in+l*6*3+middle_page*6,6*m,1,fich);

} /* this end the second part of the picture */
fwrite(nextline,3,1,fich);
}


unsigned short jerome_read(in,l,fich)
char *in;
int l;
FILE *fich;
/* read the 48 next lines in the buffer */
/* return number of the first one */
{ unsigned short k,reponse;
  int i,j;
  char *curs;
  curs=in;

  fread(&k,2,1,fich);
  reponse=REVERSE(k);
  fread(in,l,1,fich); /* this read the first line */
for(j=1;j<48;j++) /* the next 47 lines */
{
  fread(&k,2,1,fich);
  if (feof(fich))
    {
    for(i=0,curs=in+j*l;i<(48-j)*l;i++) *(curs++)=0xFF;
    return reponse;
    }
  fread(in+j*l,l,1,fich);
}
       return reponse;
}

void codifie(value,cyan,magenta,yellow)
unsigned char *value;
unsigned char cyan,magenta,yellow;
{
 /* value [couleur] {0..3}    */
 /* cyan , magenta , yellow    0..255      */
char l,k,k1,k2,k3;
l=k=k1=k2=k3=0;
if (cyan>127) {l+=1;cyan=0;}
if (magenta>127) {l+=2;magenta=0;}
if (yellow>127) {l+=4;yellow=0;}
if (l==7) {k=1;l=0;} /*noir*/
if (l>=4) {k1=1;l-=4;}
if (l>=2) {k2=1;l-=2;}
if (l>=1) {k3=1;l-=1;}

 *(value)=k; /* value[0][i] */
 *(value+1)=k3; /* value[1][i] */
 *(value+2)=k2; /* value[2][i] */
 *(value+3)=k1; /* value[3][i] */


}

void transforme (out, largeur,in)
unsigned char *out,*in;
unsigned short largeur;
{ /* out [couleur][xpos][ypos]  {0..3}{0..largeur-1}{0..5} */
  /* in [line][couleur][xpos] {0..47}{0..2}{0..largeur-1}     */
  char *cur;
  unsigned char cyan,magenta,yellow;
  unsigned char value[4];
  unsigned char cumul0,cumul1,cumul2,cumul3;
  int i,line,line2,j,k;
  for(i=0;i<largeur;i++)
  for(line=0;line<6;line++)                 /* just trust me ! */
   {
    cumul0=cumul1=cumul2=cumul3=0;
    for(line2=0;line2<8;line2++)
    {
     cyan=0xFF^(*(in+(line2+8*line)*largeur*3+i));     /* I know what I'm doing */
     magenta=0xFF^(*(in+(line2+8*line)*largeur*3+i+largeur));
     yellow=0xFF^(*(in+(line2+8*line)*largeur*3+i+2*largeur));
     codifie(value,cyan,magenta,yellow);

          cumul0+=((value[0])<<(7-line2));
          cumul1+=((value[1])<<(7-line2));
          cumul2+=((value[2])<<(7-line2));
          cumul3+=((value[3])<<(7-line2));

    }

     *(out+i*6+line)=cumul0;
     *(out+largeur*6+i*6+line)=cumul1;
     *(out+2*largeur*6+i*6+line)=cumul2;
     *(out+3*largeur*6+i*6+line)=cumul3;

   }

}

void main (argc, argv)
int argc;
char *argv[];
{
    /* facile... fichiers source et destination */

    FILE *fsrc, *fdest;

    /* hauteur et largeur */

    unsigned short w, h, w1, h1;

    int  i, j,l;
    unsigned char *in,*current,*out;
    unsigned short linenumber,linecount;

    INIT

    printf("\n%s %s\n", _prog_name, _version);
    printf("  RGB DKB file printer for Canon BJC600 on LQ mode\n");
    printf("  written by GRIMBERT Jrme, 29/09/94\n\n");


    if (argc != 3)
    {
        printf("Bad arguments number !!!\n");
        printf(USAGE, argv[0]);
        exit(BAD);
    }

    fsrc = fopen(argv[1], "rb");
    if (fsrc == NULL)
    {
        printf("First file can't be opened !!!\n");
        exit(BAD);
    }

    fdest = fopen(argv[2], "wb");
    if (fdest == NULL)
    {
        printf("Second file can't be created !!!\n");
        exit(BAD);
    }

    fread(&w, 2, 1, fsrc);
    fread(&h, 2, 1, fsrc);

    w1 = REVERSE(w);
    h1 = REVERSE(h);

    printf("File   %s\n", argv[1]);
    printf("Format %d * %d\n\n", w1, h1);
    printf("Output to %s\n",argv[2]);
    in=malloc((l=w1*3)*48); /* 3 couleurs, 48 lignes pour 48 bits/1 */
    out=malloc(w1*6*4); /* 4 couleurs, 6 lignes, 1 octets */
    if ((in==NULL)||(out==NULL)) {exit (BAD);}
    h1+=47;h1/=48;

 /*   init_map(); */

    /* for each pack of 48 lines, do... */

    printf("Processing lines...");

    linecount = 0;

    for(j=0;j<h1;j++)
    {

            current=in;
            linecount=jerome_read(in, l, fsrc);
            printf(" %d...%d",linecount,linecount+47);
            transforme(out,w1,in);
            printf(" :\n");
            generate(out,w1,fdest);
            fflush(stdout);
    } /* end for j */

    /* on libre tout */
    free(in);
    free(out);
    fclose(fsrc);
    end_page(fdest);
    fclose(fdest);

    printf("\n Done !\n");
}
