blkshift.pro

来自「basic median filter simulation」· PRO 代码 · 共 244 行

PRO
244
字号
;+; NAME:;   BLKSHIFT;; AUTHOR:;   Craig B. Markwardt, NASA/GSFC Code 662, Greenbelt, MD 20770;   craigm@lheamail.gsfc.nasa.gov;; PURPOSE:;   Shift a block of data to a new position in a file (possibly overlapping);; MAJOR TOPICS:;   File I/O;; CALLING SEQUENCE:;;   BLKSHIFT, UNIT, POS, [ DELTA, TO=TO, /NOZERO, ERRMSG=ERRMSG, ;             BUFFERSIZE=BUFFERSIZE ];; DESCRIPTION:;;  BLKSHIFT moves a block of data forward or backward, to a new;  position in a data file.  The old and new positions of the block;  can overlap safely.;;  The new position can be specified with either the DELTA parameter,;  which gives the number of bytes to move forward (positive delta) or;  backward (negative delta); or the TO keyword, which give the new;  absolute starting position of the block.;;  The block can be moved beyond the current end of file point, in;  which case the intervening gap is filled with zeros (optionally).;  The gap left at the old position of the block is also optionally;  zero-filled.    If a set of data up to the end of the file is being;  moved forward (thus making the file smaller) then;  the file is truncated at the new end.using TRUNCATE_LUN.;; INPUTS:;;   UNIT - a logical unit number, opened for reading and writing.;;   POS - POS[0] is the position of the block in the file, in bytes,;         before moving.  POS[1], if present, is the size of the block;         in bytes.  If POS[1] is not given, then the block is from;         POS[0] to the end of the file.;;   DELTA - the (optional) offset in bytes between the old and new;           positions, from the start of the block.  Positive values;           indicate moving the data forward (toward the end of file),;           and negative values indicate moving the data backward;           (toward the beginning of the file).  One of DELTA and TO;           must be specified; DELTA overrides the TO keyword.;;           Attempts to move the block beyond the end of the file will;           succeed.  A block can never be moved beyond the beginning;           of the file; it will be moved to the beginning instead.;; KEYWORD PARAMETERS:;;   TO - the absolute file offset in bytes for the new start of the;        block.  One of DELTA and TO must be specified; DELTA;        overrides the TO keyword.;;   NOZERO - if set, then newly created gaps will not be explicitly;            zeroed.  However, for some operating systems (Mac),;            zeroing is required and will be done anyway.;;   ERRMSG - If defined and passed, then any error messages will be;            returned to the user in this parameter rather than;            depending on the MESSAGE routine in IDL.  If no errors;            are encountered, then a null string is returned.  In;            order to use this feature, ERRMSG must be defined first,;            e.g.;			ERRMSG = '';			FXBGROW, ERRMSG=ERRMSG, ...;			IF ERRMSG NE '' THEN ...;;   BUFFERSIZE - the maximum buffer size for transfers, in bytes.;                Larger values of this keyword impose larger memory;                requirements on the application; smaller values will;                lead to more transfer operations.;                Default: 32768 (bytes);; MODIFICATION HISTORY:;;   Written, CM, Apr 2000;   Documented and re-written, CM, 20 Jul 2000;   Renamed from FXSHIFT to BLKSHIFT, CM, 21 Jul 2000;   Documentation, CM, 12 Dec 2002;   Truncate if moving data block forward from  the end of file ;             using TRUNCATE_LUN   W. Landsman Feb. 2005 ;   Assume since V5.5, remove VMS support  W. Landsman  Sep 2006;   Assume since V5.6, TRUNCATE_LUN available  W. Landsman Sep 2006;;-; Copyright (C) 2000, 2002, Craig Markwardt; This software is provided as is without any warranty whatsoever.; Permission to use, copy and distribute unmodified copies for; non-commercial purposes, and to modify and use for personal or; internal use, is granted.  All other rights are reserved.;-PRO BLKSHIFT, UNIT, POS0, DELTA0, NOZERO=NOZERO0, ERRMSG=ERRMSG, $              BUFFERSIZE=BUFFERSIZE0, TO=TO0  ;; Default error handling  compile_opt idl2  on_error, 2  on_ioerror, IO_FINISH  if n_params() LT 3 then begin      message = 'BLKSHIFT, UNIT, POS, DELTA'      goto, ERRMSG_OUT  endif  ;; Make sure file is open for writing, and begin parameter  ;; processing  fs = fstat(unit)  if fs.open EQ 0 OR fs.write EQ 0 then begin      message = 'File '+fs.name+' is not open for writing'      goto, ERRMSG_OUT  endif  nozero = keyword_set(nozero0)  pos_beg = floor(pos0[0])  if n_elements(pos0) GT 1 then pos_fin = floor(pos0[1])  if n_elements(pos_fin) EQ 0 then pos_fin = fs.size - 1L  if pos_beg GE fs.size then goto, GOOD_FINISH  if n_elements(to0) EQ 0 AND n_elements(delta0) EQ 0 then begin      message = 'Must specify DELTA or TO'      goto, ERRMSG_OUT  endif  ;; Parse the delta value, and enforce the file positioning  if n_elements(delta0) GT 0 then begin      delta = floor(delta0[0])      ;; Can't move beyond beginning of file      delta = ((pos_beg + delta) > 0L) - pos_beg   endif else begin      delta = (floor(to0[0]) > 0L) - pos_beg  endelse        if delta EQ 0 then goto, GOOD_FINISH  if pos_fin GE fs.size then pos_fin = fs.size - 1L  if pos_fin LT pos_beg then goto, GOOD_FINISH  if n_elements(buffersize0) EQ 0 then buffersize0 = 32768L  buffersize = long(buffersize0[0])  if buffersize LE 0 then buffersize = 32768L  ;; Seek to end of file and add zeroes (if needed)  pos_fin = pos_fin + 1L  ;; Note: Mac  cannot point beyond EOF  nozero1 = nozero  if !version.os_family EQ 'MacOS' then nozero1 = 0  if delta GT 0 AND nozero1 EQ 0 AND (pos_fin+delta GT fs.size) then begin      point_lun, unit, fs.size      nleft = (pos_fin-fs.size) + delta      while nleft GT 0 do begin          ntrans = nleft < buffersize          if n_elements(bb0) NE ntrans then bb0 = bytarr(ntrans)          writeu, unit, bb0, transfer_count=cc          if cc EQ 0 then goto, IO_FINISH          nleft = nleft - cc      endwhile  endif  ;; Now shift the data forward or backward  if delta GT 0 then begin      ;; Shift forward (toward end of file)      edat = pos_fin    ;; End of to-be-copied data segment      while edat GT pos_beg do begin          ntrans = (edat - pos_beg) < buffersize          if n_elements(bb0) NE ntrans then bb0 = bytarr(ntrans)          point_lun, unit, edat - ntrans          readu, unit, bb0, transfer_count=cc          if cc NE ntrans then goto, IO_FINISH          point_lun, unit, edat - ntrans + delta          writeu, unit, bb0, transfer_count=cc          if cc NE ntrans then goto, IO_FINISH          edat = edat - ntrans      endwhile  endif else begin      ;; Shift backward (toward beginning of file)      bdat = pos_beg   ;; Beginning of to-be-copied data segment      while bdat LT pos_fin do begin          ntrans = (pos_fin - bdat) < buffersize          if n_elements(bb0) NE ntrans then bb0 = bytarr(ntrans)          point_lun, unit, bdat          readu, unit, bb0, transfer_count=cc          if cc NE ntrans then goto, IO_FINISH          point_lun, unit, bdat - abs(delta)          writeu, unit, bb0, transfer_count=cc          if cc NE ntrans then goto, IO_FINISH          bdat = bdat + ntrans      endwhile      if pos_fin EQ fs.size  then begin                   Truncate_Lun, unit                  goto, GOOD_FINISH      endif  endelse  bb0 = [0b] & dummy = temporary(bb0)  ;; Finally, zero out the gap we created  if nozero EQ 0 then begin      if delta GT 0 then begin          point_lun, unit, pos_beg  ;; also, to be sure data is flushed          z_fin = pos_fin < (pos_beg + delta)          nleft = (z_fin - pos_beg)      endif else begin          z_beg = (pos_fin - abs(delta)) > pos_beg          nleft = (pos_fin - z_beg)          point_lun, unit, z_beg      endelse      while nleft GT 0 do begin          i = nleft < buffersize          if n_elements(bb0) NE i then bb0 = bytarr(i)          writeu, unit, bb0, transfer_count=cc          if cc EQ 0 then goto, IO_FINISH          nleft = nleft - cc      endwhile  endif  point_lun, unit, pos_beg  ;; again, to be sure data is flushed  GOOD_FINISH:  if n_elements(errmsg) GT 0 then errmsg = ''  return  IO_FINISH:  on_ioerror, NULL  message = 'ERROR: BLKSHIFT operation failed because of an I/O error'  ;; fallthrough...  ;; Error message processing.  Control does not pass through here.  ERRMSG_OUT:  if n_elements(errmsg) NE 0 then begin      errmsg = message      return  endif  message, messageEND

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?