FUNCTION xrt_resum_img, image_in, lvl_in, lvl_out,      $
                        mag_factor=mag_factor,          $
                        quiet=quiet,   verbose=verbose, $
                        qabort=qabort, qstop=qstop

;==========================================================================
;+
; PROJECT:
;       Solar-B / XRT
;
; NAME:
;       XRT_RESUM_IMG    (XRT Re-summing Image)
;
; CATEGORY:
;       Image manipulation
;
; PURPOSE:
;       Re-size an XRT image, while keeping the signal levels constant.
;
; CALLING SEQUENCE:
;       Result = XRT_RESUM_IMG(image_in, lvl_in, lvl_out
;                              [,mag_factor=mag_factor] [,/quiet]
;                              [, /verbose] [,qabort=qabort] [,/qstop])
;
; INPUTS:
;       IMAGE_IN   - [Mandatory] (number array, [Nx,Ny])
;                    A single 2D image array.
;       LVL_IN     - [Mandatory] (integer) The summing level of 
;                    input "image_in". This corresponds to the value
;                    of the CHIP_SUM tag in the XRT FITS header.
;                    1: 1x1 summing
;                    2: 2x2 summing
;                    4: 4x4 summing
;                    8: 8x8 summing
;       LVL_OUT    - [Mandatory] (integer) The desired summing level 
;                    of the output image array. See LVL_IN entry for
;                    allowed levels.
;
; KEYWORDS:
;       /QUIET     - [Optional] (Boolean) Suppress messages (see Note #1).
;       /VERBOSE   - [Optional] (Boolean) Print out extra information.
;                    Overrides "/quiet" (see Note #1).
;       /QSTOP     - [Optional] (Boolean) For debugging.
;
; OUTPUTS:
;       Result     - (float array, [Nxx,Nyy]) The output image is a
;                    resized version of "image_in", where
;                      Nxx = Nx * "lvl_out" / "lvl_in",
;                      Nyy = Ny * "lvl_out" / "lvl_in".
;                    The total signal is preserved.
;                    If "lvl_out" < "lvl_in" (i.e., the image is made 
;                    larger), then the signal within an "image_in" pixel
;                    is distributed uniformly into its expanded area.
;       MAG_FACTOR - [Optional] (float) Value used for resizing the
;                    image dimensions (Nx,Ny).
;       QABORT     - [Optional] (Boolean) Indicates that the program
;                    exited gracefully without completing. (Might be
;                    useful for calling programs.)
;                    0: Program ran to completion.
;                    1: Program aborted before completion.
;
; EXAMPLE:
;
;       Re-sum an XRT image to 1x1.
;       IDL> img_out = xrt_resum_img(image, index.chip_sum, 1)
;
; COMMON BLOCKS:
;       None.
;
; NOTES:
;
;       1) There are three levels of verbosity.
;          a) "verbose" = highest priority. All errors and messages are
;                         displayed. ("if q_vb")
;          b) "quiet" = lower priority. No errors or messages are
;                       displayed. ("if q_qt")
;          c) neither = lowest priority. All errors and some messages are
;                       displayed. ("if not q_qt")
;
;       2) The summing levels are limited to the XRT possibilities,
;          and are limited to be the same in both directions.
;
; CONTACT:
;
;       Comments, feedback, and bug reports regarding this routine may be
;       directed to this email address:
;                xrt_manager ~at~ head.cfa.harvard.edu
;
; MODIFICATION HISTORY:
;
progver = 'v2006-Nov-30' ;--- (MW) Written.
;
;
;-
;===========================================================================


;=== Check inputs & other initial prep ================================


  ;=== Set Booleans which control print statements.
  ;=== Keyword "verbose" overrules "quiet".
  q_vb = keyword_set(verbose)
  q_qt = keyword_set(quiet) and (not q_vb)

  ;=== Announce version of <xrt_resum_img.pro>.
  if q_vb then box_message, 'XRT_RESUM_IMG: Running ' + prognam + $
                            ' ' + progver + '.'
  if q_vb then print, 'XRT_RESUM_IMG: Performing initial setup...'

  ;=== Initialize program constants.
  prognam = 'XRT_RESUM_IMG.PRO'

  ;=== Set some keyword Booleans.
  qstop   = keyword_set(qstop)
  qabort  = 0B

  ;=== Make sure "lvl_in" has a legal value.
  case lvl_in of
    1:
    2:
    4:
    8:
    else: begin
            if (not q_qt) then box_message,                           $
              ['XRT_RESUM_IMG: Input "lvl_in" does not match one of', $
               '               the allowed levels. Aborting...']
            qabort = 1B
            return, image_in
          end
  endcase

  ;=== Make sure "lvl_out" has a legal value.
  case lvl_out of 
    1:
    2:
    4:
    8:
    else: begin
            if (not q_qt) then box_message,                            $
              ['XRT_RESUM_IMG: Input "lvl_out" does not match one of', $
               '               the allowed levels. Aborting...']
            qabort = 1B
            return, image_in
          end
  endcase 

  if q_vb then print, '                                       ...OK'


;=== Perform resizing =================================================

  if q_vb then print, 'XRT_RESUM_IMG: Performing resizing...'

  if (lvl_in eq lvl_out) then begin
    if q_vb then print, 'XRT_RESUM_IMG: No resumming necessary.'
    return, image_in
  endif

  ;=== From here on, we know that (lvl_in ne lvl_out).
  mag_factor = float(lvl_in)/lvl_out
  ;=== Incoming image dimensions.
  nx0 = n_elements(image_in[*,0])
  ny0 = n_elements(image_in[0,*])
  ;=== Outgoing image dimensions.
  nx1 = long(nx0 * mag_factor)
  ny1 = long(ny0 * mag_factor)


  if (lvl_in lt lvl_out) then begin
    ;=== The number of pixels changes as (mag_factor^2), and must
    ;=== conserve total signal.
    image_out = rebin(image_in, nx1, ny1, /sample) / (mag_factor^2)
  endif


  if (lvl_in gt lvl_out) then begin
    ;=== Check whether "image_in" is an irreducible size.
    if (((nx1/mag_factor) ne nx0) or ((ny1/mag_factor) ne ny0)) then begin
      if (not q_qt) then box_message, $
              ['XRT_RESUM_IMG: Input "image_in" size cannot be reduced', $
               '               by these integer multiples. Aborting...']
      qabort = 1B
      return, image_in
    endif
    ;=== The number of pixels changes as (mag_factor^2), and must
    ;=== conserve total signal.
    image_out = rebin(float(image_in), nx1, ny1) / (mag_factor^2)
  endif

  if q_vb then print, '                                  ...OK'


;=== Finish up ========================================================

  return, image_out


END ;======================================================================

