PRO PIXMAPS2MPEG, mpegFileName, win_index, IMG_REBIN=img_rebin, WHIRLGIF=WHIRLGIF, $
	SCALE=scale, REFERENCE=reference, PNG=png,mframes=mframes,inline=inline,$
	firstframe=firstframe,idlencode=idlencode,good=good,force_win_index=force_win_index, lastframe=lastframe

; $Id: pixmaps2mpeg.pro,v 1.43 2019/02/25 20:08:18 secchia Exp $
;
; INPUTS:
;  mpegFileName	   STRING, Name of output file
;  win_index	BYTARR	Array of pixmap indices or a STRARR list of gif files
;
; KEYWORDS:
;  IMG_REBIN = [desired x size, desired y size]
;  WHIRLGIF	Set if also creating animated GIF
;  SCALE        Compression factor: 4,8,16,24 (4 is low compression)
;  REFERENCE	High quality='DECODED', Low quality='ORIGINAL'
;  mframes    number of time to repeat each frame to control play speed. 
;  idlencode   set to use the idl mpeg_encoder
;  good = a list of good frames from scc_movieout
;  inline : total number of frames to be written when called with in a for loop (for example see call from scc_save_mvframe.pro)
;  lastframe set to indicate last frame of inline movie
;
; MODIFICATIONS:
; $Log: pixmaps2mpeg.pro,v $
; Revision 1.43  2019/02/25 20:08:18  secchia
; change -q:v back to -qscale ffmpeg did not reconize it?
;
; Revision 1.42  2017/06/20 16:51:29  nathan
; mk mpegfilename dir
;
; Revision 1.41  2014/08/05 16:15:21  hutting
; set keyword pngs if output is ffmpeg
;
; Revision 1.40  2014/06/10 19:04:52  hutting
; removed default to png
;
; Revision 1.39  2014/05/09 17:37:42  avourlid
; Fixes for ffmpeg compatibility: (1) Forced output frame format to PNG. (2) Replaced -qscale w/ -q:v. (3) Added -pix_fmt yuv420p.
;
; Revision 1.38  2013/12/13 18:05:22  mcnutt
; changed ffmpeg to use qscale instead of qmin/qmax, qscale is still found in the ffmpeg documentation
;
; Revision 1.37  2013/12/13 15:49:28  mcnutt
; corrected if statement error
;
; Revision 1.36  2013/12/13 15:41:56  mcnutt
; added .mpg back to if statement used when mpeg_encode is not found
;
; Revision 1.35  2013/12/13 14:00:23  mcnutt
; removed sameq from ffmpeg call and removed .mpg from ffmpeg if statement
;
; Revision 1.34  2012/08/07 18:23:01  nathan
; correctly call ffmpeg if input was .mpg and mpeg_encode not found
;
; Revision 1.33  2012/08/01 17:39:38  mcnutt
; added lastframe keyword if set it makes the mpeg movie
;
; Revision 1.32  2012/07/17 20:59:54  nathan
; fix mpgcmd
;
; Revision 1.31  2012/07/13 22:59:08  nathan
; use ffmpeg if mpeg_encode not found
;
; Revision 1.30  2012/07/13 17:58:21  mcnutt
; add inline keyword def.
;
; Revision 1.29  2012/06/01 15:29:18  mcnutt
; added keyword force_win_index to egnore imgs if defined in common block
;
; Revision 1.28  2012/04/05 14:33:06  nathan
; edit comment
;
; Revision 1.27  2012/04/05 13:35:09  mcnutt
; will now except a list of gif files as input
;
; Revision 1.26  2011/12/23 16:39:05  avourlid
; replaced qmin, qmax with sameq in the ffmpeg call to maintain image quality
;
; Revision 1.25  2011/12/23 16:30:56  avourlid
; added /DITHER keyword to Color_QUan to improve qualite of output gif files
;
; Revision 1.24  2011/11/01 12:34:39  mcnutt
; ffmpeg uses qmin and qmax to set compression values
;
; Revision 1.23  2011/10/17 20:08:33  nathan
; code comments
;
; Revision 1.22  2011/10/17 17:51:51  mcnutt
; will write a ffmpeg .mpg movie if input ext eq .ffmpg
;
; Revision 1.21  2011/04/29 15:35:20  avourlid
; Corrected ffmpeg call, removed if statements for scale keyword
;
; Revision 1.20  2011/04/29 15:14:55  mcnutt
; added sameq to ffmpeg call
;
; Revision 1.19  2011/01/14 22:57:02  nathan
; define exstat for ffmpeg
;
; Revision 1.18  2011/01/14 20:08:54  nathan
; print cmd for ffmpeg and whirlgif
;
; Revision 1.17  2011/01/06 15:47:34  nathan
; fix typo
;
; Revision 1.16  2011/01/05 18:29:51  nathan
; use new binfound.pro to test giftopnm
;
; Revision 1.15  2010/12/23 19:12:08  nathan
; check mpeg_encode exit status; fix mframes default definition
;
; Revision 1.14  2010/12/22 17:58:56  mcnutt
; added ffmpeg
;
; Revision 1.13  2010/04/22 17:01:09  mcnutt
; sized image for IDL mpeg encode to be a factor of 16
;
; Revision 1.12  2010/04/12 18:06:28  mcnutt
; added idl encode option
;
; Revision 1.11  2010/02/24 18:10:53  mcnutt
; forces image size to multipuls of 16
;
; Revision 1.10  2009/11/30 14:25:21  mcnutt
; added inline keyword and common block
;
; Revision 1.9  2009/10/15 13:33:03  mcnutt
; corrected image for loop single frame movies
;
; Revision 1.8  2009/10/14 12:21:26  mcnutt
; replaced lost if statment for img_rebin
;
; Revision 1.7  2009/10/09 18:34:40  mcnutt
; added keyword mframes = number of times a frame is writen to the movie
;
; Revision 1.6  2009/06/17 19:15:12  secchib
; nr - always make TMPDIR
;
; Revision 1.5  2009/04/06 14:31:46  nathan
; oops
;
; Revision 1.4  2009/04/03 21:10:01  nathan
; expand test cases for ppm not found
;
; Revision 1.3  2008/05/08 19:38:27  nathan
; changed order of binary selection logic
;
; Revision 1.2  2008/04/28 19:28:15  nathan
; do color_quan if 24-bit result from ftvread
;
; Revision 1.1  2008/03/20 22:02:45  nathan
; moved from lasco/idl/reduce
;
;  2/2/01, nbr - Make more robust in use of IMG_REBIN
;	010216 - the Jake - Made corrections to all SPAWN commands
;					Added /SH to all SPAWN commands
;					Added -ef to /usr/bin/ps command
;	010220 - the Jake - Added gawk to /usr/bin/ps
;	2001.11.02, nbr - Add SCCS version stamp
;	2002.02.25, nbr - Always write temporary gifs in /tmp
;	020329	Jake	- changed idl pid to echo $$;  running 2 copies of
;				idl/make_daily_mvi_all results in both
;				jobs using the same tmp directory
;
;	020411 Jake	- create GETIDLPID() for general use and inserted it 
;			here to replace the previous stuff
;	030714 jake - using pngs instead of gifs
;	030715 jake - alert is not a command
;				replaced with message
;	030715 jake PNGs appear to be working,
;				but not correctly for ssw_idl56
;	030715 jake Removed PNG Rotate during write
;	050720 a.wang - accomodate linux which output
;   	061013 n.rich - Use SSW_BINARIES for mpeg_encode and whirlgif if not in
;   	    	    	path. (linux_x86/mpeg_encode does not seem to be working)
;
;	10/13/06 @(#)pixmaps2mpeg.pro	1.15 - NRL LASCO IDL Library
;-
COMMON pmap2mpeg,pmapstrut
COMMON WSCC_MKMOVIE_COMMON, swmoviev, debug_on, rgb, imgs, coordsab, findx, textframe

        
      if datatype(win_index) eq 'STR' then gifsin=1 else gifsin=0
      if gifsin eq 0 then begin
     	szim=size(win_index)
        IF szim[0] lt 2 THEN BEGIN
   	   WSET, win_index(0)
     	   xSize = !D.X_SIZE
     	   ySize = !D.Y_SIZE
        ENDIF 
        IF szim[0] eq 2 THEN BEGIN
     	   xSize = n_elements(win_index(*,0))
     	   ySize = n_elements(win_index(0,*))
        ENDIF 
        IF szim[0] eq 3 THEN BEGIN
     	   xSize = n_elements(win_index(0,*,0))
     	   ySize = n_elements(win_index(0,0,*))
        ENDIF 
    endif	


   BREAK_FILE, mpegFileName, a, dir, name, ext
   if ext eq '.mov' or ext eq '.avi' or ext eq '.ffmpg' or ext eq '.ffm' then ffmpeg=1 else ffmpeg=0
   if ffmpeg eq 1 or keyword_set(png) then png = 1 else png=0
   IF not (file_exist(dir)) THEN spawn,'mkdir '+dir 

;*****
;png=1
;****

    if ~keyword_set(scale) then scale = 4 ;Default is low compression
    if ~keyword_set(inline) then begin
      nFrames = N_ELEMENTS(win_index)
      len=nFrames
      first=1
    endif else begin
      nFrames = 1
      len=inline
      if keyword_set(firstframe) then first=1 else first=0
    endelse

    if keyword_set(idlencode) then idlencode=1 else idlencode=0
    BREAK_FILE, mpegFileName, a, dir, name, ext
    if ext eq '.idlmpg' then begin
      idlencode=1
      mpegFileName=dir+name+'.mpg'
    endif

    if gifsin eq 0 then begin
    ; Load current color table into byte arrays
      TVLCT, red, green, blue, /GET
      red = BYTE(red)
      green = BYTE(green)
      blue = BYTE(blue)
    endif

    ON_IOERROR, badWrite


  if first eq 1 then begin
    IF KEYWORD_SET(mframes) THEN mframes=mframes else mframes=1
    if ~idlencode eq 1 then begin
      if mframes ne 0 then nDigits = 1+FIX(ALOG10(len*mframes)) else nDigits = 1+FIX(ALOG10(len))
      formatString = STRCOMPRESS('(i'+STRING(nDigits)+'.'+STRING(nDigits)$
                +             ')', /REMOVE_ALL)

    ; Make a temporary directory if necessary or clear it otherwise'
    ;** GET PID OF IDL SESSION FOR UNIQUE TEMPORARY FILE NAME
    ;FILE_ACC, './', exist, read, write, execute, filetype
    ;IF (write NE 1) THEN dir = '/tmp/' ELSE dir = './'
      dir = '/tmp/'	; nbr, 2/25/02
;    SPAWN, "/usr/bin/ps -ef | grep idl | grep -v grep | gawk '{print $2}'", result  & result = result(0)
;    SPAWN, "/bin/echo $$", result  & result = result [0]	;	020329 Jake
;    spawn, "/bin/ps -ef | grep `echo $$` | grep sh | gawk '{print $3}' | grep -vs `echo $$`", result 	; 020329 Jake
;    result = result[0]
;    idl_pid = STRCOMPRESS(STRMID(result, 0, 6),/REMOVE_ALL)

      idl_pid = GETIDLPID()	;	020411 Jake
      TMPDIR = dir+'idl2mpeg.frames'+idl_pid

    ; USUALLY $LEB_IMG/idl2mpeg.frames??????
      PRINT, "Using TMPDIR :" + TMPDIR
      SPAWN, 'if [ -d ' + TMPDIR + ' ]; then echo "exists"; fi', result 
      dirExists = result(0) EQ 'exists'
	;	IF dirExists THEN SPAWN, '/bin/rm -rf ' + TMPDIR + '/*'  $
      IF dirExists THEN SPAWN, '/bin/rm -rf ' + TMPDIR  
      SPAWN, 'mkdir ' + TMPDIR 

    ; Write each frame into TMPDIR as an 8-bit .gif image file
	;	030714 using png instead of gif
	IF KEYWORD_SET ( PNG ) THEN $
		extension = '.png' $
	ELSE $
		extension = '.gif'
    
      pmapstrut={TMPDIR:TMPDIR, extension:extension,  mframes:mframes, formatString:formatString, len:len, count:0}
    endif else begin
     ;IDL MPEG
      if xsize/16.-xsize/16 gt 0 then xsize=(xsize/16+1)*16 ;set image size to a factor of 16 for mpeg encode
      if ysize/16.-ysize/16 gt 0 then ysize=(ysize/16+1)*16 ;set image size to a factor of 16 for mpeg encode
      mpegID = MPEG_Open([xSize, ySize], Filename=mpegFileName, Quality=scale)
      pmapstrut={mframes:mframes,  len:len, count:0, mpegID:mpegID}
    endelse

  endif

    FOR frameNum = 0, nFrames-1 DO BEGIN
      if gifsin eq 0 then begin
        if ~keyword_set(inline) then begin
          if datatype(imgs) eq 'BYT' and ~keyword_set(force_win_index)then begin
     	    szim=size(imgs)
            if keyword_set(good) then inum=good(frameNum) else inum=frameNum
            IF szim[0] GT 3 THEN img=imgs(*,*,*, inum) else img=imgs(*,*, inum)
          endif else begin
            WSET, win_index(frameNum)
	    img = ftvread(0, 0, xSize, ySize)
          endelse 
        endif else begin
     	  szim=size(win_index)
          IF szim[0] GE 2 THEN img=win_index else begin
            WSET, win_index
	    img = ftvread(0, 0, xSize, ySize)
          endelse
	endelse
      
     	szim=size(img)
    	IF szim[0] GT 2 THEN img=Color_Quan(temporary(img), 1, red, green, blue, COLORS=256, /dither)
     	szim=size(img)
        if (szim(1)/16.)-(szim(1)/16) gt 0 then img=[img,[bytarr((1+szim(1)/16)*16 -szim(1),szim(2))]]
        if (szim(2)/16.)-(szim(2)/16) gt 0 then img=rotate([rotate(img,1),rotate([bytarr(n_Elements(img(*,0)),(1+szim(2)/16)*16 -szim(2))],1)],3)
        IF KEYWORD_SET(IMG_REBIN) THEN $
	        IF (xSize MOD img_rebin(0) EQ 0) AND ysize MOD img_rebin[1] EQ 0 THEN $
    		    img = REBIN(img, img_rebin(0), img_rebin(1)) $
	        ELSE $
    		    img = CONGRID(img, img_rebin(0), img_rebin(1), /INTERP)
;IDL MPEG
         if idlencode eq 1 then begin
            img=rotate(img,7)
            image24=bytarr(3,n_Elements(img(*,0)),n_Elements(img(0,*)))
            image24[0,*,*] = red(img[*,*])
            image24[1,*,*] = green(img[*,*])
            image24[2,*,*] = blue(img[*,*])
         endif 
       endif

         FOR mfr=0,pmapstrut.mframes -1  DO BEGIN
          if ~idlencode eq 1 then begin
            fileName = pmapstrut.TMPDIR + '/frame.' + STRING(pmapstrut.count*pmapstrut.mframes+mfr,FORMAT=pmapstrut.formatString) + pmapstrut.extension
            if gifsin eq 0 then begin
              IF KEYWORD_SET ( PNG ) THEN $
			WRITE_PNG, filename, img, red, green, blue $
		ELSE $
                   WRITE_GIF, fileName, img, red, green, blue
	    endif else begin
	       syscmd='cp '+win_index(frameNum)+' '+fileName
               spawn,syscmd
	    endelse   
          endif else begin
;IDL MPEG
            fnum=pmapstrut.count*pmapstrut.mframes+mfr         
	    MPEG_Put, pmapstrut.mpegID, Image=image24, Frame=fnum
          endelse
       ENDFOR
       pmapstrut.count=pmapstrut.count+1
    ENDFOR

if keyword_set(lastframe) then pmapstrut.len = pmapstrut.count

if pmapstrut.count eq pmapstrut.len then begin 
    bindir=concat_dir(getenv('SSW_BINARIES'),'exe')
    bindir=concat_dir(bindir,!version.os+'_'+!version.arch)
    spawn,'which mpeg_encode' ,result
    print,result
    mpgencok=NOT(strpos(result[0], 'not found') GE 0 OR result[0] EQ '')
    IF mpgencok THEN mpgcmd=result[0] ELSE $
    mpgcmd=concat_dir(bindir,'mpeg_encode')

   BREAK_FILE, mpegFileName, a, dir, name, ext
   if ext eq '.mov' or ext eq '.avi' or ext eq '.ffmpg' or ext eq '.ffm' then ffmpeg=1 else ffmpeg=0

    IF ext EQ '.mpg' and ~file_exist(mpgcmd) THEN BEGIN
    	print,mpgcmd,' not found; trying ffmpeg instead '
	ffmpeg=1
    ENDIF

    if idlencode eq 1 then begin
    ;IDL MPEG
    	MPEG_Save, pmapstrut.mpegID
    	MPEG_Close, pmapstrut.mpegID
    	exstat=0
    endif else begin

    if ffmpeg eq 1 then begin
;       cmptxt=' -qmin '+string(scale,'(i2)')+' -qmax '+string(scale,'(i2)')
;       if keyword_set(reference) then if strpos(reference,'sameq') gt
;       -1 then 

    	spawn,'which ffmpeg' ,result
	print,result
        cmptxt=' -qscale '+string(scale,'(i2)')	;	' -qmin '+string(scale,'(i2)')+' -qmax '+string(scale,'(i2)')
;       if keyword_set(reference) then if strpos(reference,'sameq') gt -1 then cmptxt=' -sameq'
       if ext eq '.ffmpg' or ext eq '.mpg' then begin
           mpegFileName=dir+name+'.mpg'
	   cmd='ffmpeg -y -i '+pmapstrut.TMPDIR+'/frame.%'+string(strmid(pmapstrut.FORMATSTRING,2,1),'(i2.2)')+'d'+pmapstrut.EXTENSION+cmptxt+' '+mpegFileName
       endif else cmd='ffmpeg -y -r 6 -i '+pmapstrut.TMPDIR+'/frame.%'+string(strmid(pmapstrut.FORMATSTRING,2,1),'(i2.2)')+'d'+pmapstrut.EXTENSION+cmptxt+' -pix_fmt yuv420p -r 6 '+mpegFileName
       print,cmd
       spawn,cmd,EXIT_STATUS=exstat 
    endif else begin

;--Not ffmpeg

    bindir=concat_dir(getenv('SSW_BINARIES'),'exe')
    bindir=concat_dir(bindir,!version.os+'_'+!version.arch)
    convert_type = 'PNM'
    converter = 'giftopnm'

    IF KEYWORD_SET ( PNG ) THEN BEGIN
    	converter = 'pngtopnm'
    ENDIF ELSE $
    IF not (binfound('giftopnm')) THEN BEGIN
	    ;** get gif converter
			; try PPM
    	convert_type = 'PPM'
    	converter = 'giftoppm'
    ENDIF


;    IF KEYWORD_SET(SCALE) THEN ascale = STRTRIM(scale,2) ELSE ascale = '4'
    ascale = STRTRIM(scale,2)
    IF KEYWORD_SET(REFERENCE) THEN aref = STRUPCASE(STRTRIM(reference,2)) ELSE aref = 'DECODED'

    ; Build the mpeg parameter file
    first=STRING(0,FORMAT=pmapstrut.formatString)
    if pmapstrut.mframes ne 0 then last=STRING(pmapstrut.len*pmapstrut.mframes-1,FORMAT=pmapstrut.formatString) else last =STRING(pmapstrut.len-1,FORMAT=pmapstrut.formatString)
    paramFile = pmapstrut.TMPDIR + '/idl2mpeg.params'
    OPENW, unit, paramFile, /GET_LUN
    PRINTF, unit, 'PATTERN     IBBPBBPBBPBB'
    PRINTF, unit, 'OUTPUT      ' + mpegFileName
    PRINTF, unit, 'GOP_SIZE 12'
    PRINTF, unit, 'SLICES_PER_FRAME  1'
    PRINTF, unit, 'BASE_FILE_FORMAT  '+convert_type
    PRINTF, unit, 'INPUT_CONVERT  ' + converter + ' *'
    PRINTF, unit, 'INPUT_DIR   '+pmapstrut.TMPDIR
    PRINTF, unit, 'INPUT'
    PRINTF, unit, 'frame.*' + pmapstrut.extension + ' ['+ first  + '-' + last + ']'
    PRINTF, unit, 'END_INPUT'
    PRINTF, unit, 'PIXEL    HALF'
    PRINTF, unit, 'RANGE    8'
    PRINTF, unit, 'PSEARCH_ALG LOGARITHMIC'
    PRINTF, unit, 'BSEARCH_ALG SIMPLE'
    PRINTF, unit, 'IQSCALE     '+ascale
    PRINTF, unit, 'PQSCALE     '+ascale
    PRINTF, unit, 'BQSCALE     '+ascale
    PRINTF, unit, 'REFERENCE_FRAME   '+aref
    PRINTF, unit, 'FORCE_ENCODE_LAST_FRAME'
    FREE_LUN, unit

    ; spawn a shell to process the mpeg_encode command
    
    spawn,'which mpeg_encode' ,result
    print,result
    IF NOT(STRPOS(result[0], 'not found') GE 0 OR result[0] EQ '') THEN bindir=''
    cmd=mpgcmd+' ' + paramFile
    print,cmd
    spawn,['cat',paramfile],/noshell
    SPAWN, cmd, EXIT_STATUS=exstat 

    IF KEYWORD_SET(WHIRLGIF) AND NOT KEYWORD_SET ( PNG ) THEN BEGIN
    	spawn,'which whirlgif' ,result
	IF NOT(STRPOS(result[0], 'not found') GE 0 OR result[0] EQ '') THEN bindir=''
	cmd=concat_dir(bindir,'whirlgif')+' -o '+mpegFileName+'.gif'+' -loop 5 -time 5 '+pmapstrut.TMPDIR+'/frame*.gif'
        print,cmd
	SPAWN, cmd, EXIT_STATUS=exstat 
    ENDIF

  endelse   ; not ffmpeg
  print,' Used ',cmd
    ; clean temp dir
	;    SPAWN, '/bin/rm -rf ' + TMPDIR + '/*' 	; !!!! DANGER! Don't do this !!!!
    IF exstat NE 0 THEN message, 'Unable to write MPEG file!'
    
    SPAWN, '/bin/rm -rf ' + pmapstrut.TMPDIR 

  endelse   ; not idlencode
endif	    ; pmapstrut.count eq pmapstrut.len

    RETURN


    badWrite:
    message, 'Unable to write MPEG file!'
    ;alert, 'Unable to write MPEG file!'


END
