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

#ifdef __STDC__
#define ARGS(alist) alist
#else
#define ARGS(alist) ()
#endif

#define put_byte(A) (*pb)((byte)(A)); Nbyte++

typedef unsigned char byte;

/***********************************************************************
 *                                                                     *
 * Name: PPMencode                                   Date:    11.01.93 *
 * Author: E.Chernyaev (IHEP/Protvino)               Revised:          *
 *                                                                     *
 * Function: Output image in PPM format (portable pixmat file format)  *
 *                                                                     *
 * Input: Width      - image width                                     *
 *        Height     - image height                                    *
 *        Ncol       - number of colors                                *
 *        R[]        - red components                                  *
 *        G[]        - green components                                *
 *        B[]        - blue components                                 *
 *        ScLine[]   - array for scan line (byte per pixel)            *
 *        get_scline - user routine to read scan line:                 *
 *                       get_scline(y, width, ScLine)                  *
 *        pb         - user routine for "put_byte": pb(b)              *
 *                                                                     *
 * Return: size of PPM                                                 *
 *                                                                     *
 ***********************************************************************/
long PPMencode(Width, Height, Ncol, R, G, B, ScLine, get_scline, pb)
          int  Width, Height, Ncol;
          byte R[], G[], B[], ScLine[];
          void (*get_scline) ARGS((int, int, byte *)), (*pb) ARGS((byte));
{
  
  long    Nbyte;
  char    s[20];
  int     i, x, y, maxcol;

  /*   C H E C K   P A R A M E T E R S   */
  
  if (Width <= 0 || Width > 4096 || Height <= 0 || Height > 4096) {
    fprintf(stderr,
            "\nPPMencode: incorrect image size: %d x %d\n", Width, Height);
    return 0;
  }

  if (Ncol <= 0 || Ncol > 256) {
    fprintf(stderr,"\nPPMencode: wrong number of colors: %d\n", Ncol);
    return 0;
  }

  /*   F I N D   M A X   C O L O R - C O M P O N E N T   */   

  maxcol = 0;
  for (i=0; i<Ncol; i++) {
    if (maxcol < R[i]) maxcol = R[i];
    if (maxcol < G[i]) maxcol = G[i];
    if (maxcol < B[i]) maxcol = B[i];
  }

  /*   P U T    O U T    H E A D E R   */

  Nbyte = 0; 
  sprintf(s,"P6 %d %d %d\n", Width, Height, maxcol);
  for (i=0; i<strlen(s); i++) {
    put_byte(s[i]);
  }

  /*   P U T    O U T    D A T A   */

  for(y=0; y<Height; y++) {
    (*get_scline)(y, Width, ScLine);
    for (x=0; x<Width; x++) {
      i = ScLine[x];
      put_byte(R[i]);
      put_byte(G[i]);
      put_byte(B[i]);
    }
  }
  return Nbyte;
}
