diff options
Diffstat (limited to 'sys/imio/iki/fxf/fxfexpandh.x')
-rw-r--r-- | sys/imio/iki/fxf/fxfexpandh.x | 375 |
1 files changed, 375 insertions, 0 deletions
diff --git a/sys/imio/iki/fxf/fxfexpandh.x b/sys/imio/iki/fxf/fxfexpandh.x new file mode 100644 index 00000000..9e00d582 --- /dev/null +++ b/sys/imio/iki/fxf/fxfexpandh.x @@ -0,0 +1,375 @@ +include <imio.h> +include <imhdr.h> +include <mii.h> +include <fset.h> +include <mach.h> +include <syserr.h> +include "fxf.h" + +define MIN_BUFSIZE 2880 + + +# FXF_EXPANDH -- Routine to expand all the headers of a MEF file. The calling +# routine only requires that extension 'group' be expanded but when dealing +# with large MEF files with many extensions this procedure can take a long +# time if the application code wants to expand more than one header. +# fxf_expandh will expand all the headers in the file so they will have at +# least 'nlines' blank cards. + +procedure fxf_expandh (in_fd, out_fd, nlines, group, nbks, hdroff, pixoff) + +int in_fd #I input file descriptor +int out_fd #I output file descriptor +int nlines #I minimum number of blank cards +int group #I group that initiated the expansion +int nbks #I numbers of blocks to expand group 'group' +int hdroff #O new offset for beginning of 'group' +int pixoff #0 new offset for beginning of data + +pointer hd, ip, op, buf +char line[80], endl[80] +int gn, newc, k, nchars, nbk, hsize +int fxf_xaddl(), read() + +int bufsize, psize, rem, hoffset, poffset +int note(), fstati() +errchk malloc, read, write + +begin + # In case nlines is zero set a minimum > 0. + nlines = max (nlines, 10) + + # Initialize a blank line. + call amovks (" ", line, LEN_CARD) + + # Initialize END card image. + call amovc ("END", endl, 3) + call amovks (" ", endl[4], LEN_CARD-3) + + call fseti (in_fd, F_ADVICE, SEQUENTIAL) + call fseti (out_fd, F_ADVICE, SEQUENTIAL) + + bufsize = max (MIN_BUFSIZE, fstati (in_fd, F_BUFSIZE)) + call malloc (buf, bufsize, TY_CHAR) + + gn = 0 + hd = buf + + repeat { + hd = buf + if (group == gn) + hdroff = note(out_fd) + + # Read and write header information. The last block must + # have the END card and is output from this routine. + + iferr (call fxf_xhrd (in_fd, out_fd, Memc[buf], bufsize, hoffset, + poffset, hsize)) + break + + # Determine the number of cards to expand. newc is in blocks + # of 36 cards. 0, 36, 72, ... + + newc = fxf_xaddl (buf, hsize, nlines) + + # expand the given group at least one block + if (newc == 0 && nbks > 0 && group == gn) + newc = nbks * 36 + + # OP points to the top of the last block read, IP to the bottom. + op = buf + hsize - FITS_BLOCK_BYTES + ip = buf + hsize + + if (newc == 0) { + # Leave space for the END card. + ip = ip - 80 + } else { + # Write current buffer before writing blanks. + call miipak (Memc[op], Memc[op], FITS_BLOCK_BYTES, + TY_CHAR,MII_BYTE) + call write (out_fd, Memc[op], FITS_BLOCK_CHARS) + + # Use the same buffer space since we are using blanks + ip = ip - FITS_BLOCK_BYTES + op = ip + } + + # Write the blank cards. + do k = 1, newc-1 { + call amovc (line, Memc[ip], LEN_CARD) + ip = ip + LEN_CARD + if (mod (k,36) == 0) { + # We have more than one block of blanks. + call miipak (Memc[op], Memc[op], nchars, TY_CHAR, MII_BYTE) + call write (out_fd, Memc[op], FITS_BLOCK_CHARS) + + # Notice we used the same buffer space + ip = ip - FITS_BLOCK_BYTES + op = ip + } + } + + # Finally the END card. + call amovc (endl, Memc[ip], LEN_CARD) + nchars = 2880 + call miipak (Memc[op], Memc[op], nchars, TY_CHAR, MII_BYTE) + call write (out_fd, Memc[op], nchars/2) + + # Get the number of blocks of pixel data to copy. We are not + # changing anything; it is straight copy. + + psize = (hoffset - poffset) + + nbk = psize / bufsize + rem = mod(psize,bufsize) + + if (group == gn) + pixoff = note(out_fd) + + do k = 1, nbk { + nchars = read (in_fd, Memc[buf], bufsize) + call write (out_fd, Memc[buf], bufsize) + } + if (rem > 0) { + nchars = read (in_fd, Memc[buf], rem) + call write (out_fd, Memc[buf], rem) + } + gn = gn + 1 + } + + call mfree (buf, TY_CHAR) +end + + +# FXF_XHRD -- Procedure to read 2880 bytes blocks of header from 'in' +# and copy them to 'out'. The last block read contains the END card +# and is pass to the calling routine which will write it out to 'out. + +procedure fxf_xhrd (in, out, buf, bufsize, hoffset, poffset, hsize) + +int in #I Input file descriptor +int out #I output file descriptor +char buf[ARB] #I Working buffer +int bufsize #I Workign buffer size +int hoffset #O Header offset for next group +int poffset #O Data offset for current group +int hsize #O Number of cards read in header + +pointer sp, hb +int nblks, totpix, i, j, ip, nchars +int strncmp(), note(), read() +bool end_card, fxf_xn_decode_blk1() + +include "fxfcache.com" +errchk syserr, read, write + +begin + call smark (sp) + call salloc (hb, 1440, TY_CHAR) + + hoffset = note (in) + + # Read first block of header. + nchars = read (in, Memc[hb], FITS_BLOCK_CHARS) + if (nchars == EOF) { + call sfree (sp) + call syserr (SYS_FXFRFEOF) + } + + call miiupk (Memc[hb], buf, FITS_BLOCK_BYTES, MII_BYTE,TY_CHAR) + end_card = fxf_xn_decode_blk1 (buf, totpix) + if (!end_card) { + call miipak (buf, Memc[hb], FITS_BLOCK_BYTES, TY_CHAR, MII_BYTE) + call write (out, Memc[hb], FITS_BLOCK_CHARS) + } + ip = FITS_BLOCK_BYTES + 1 + + nblks = 1 + if (!end_card) { + # Continue reading header until the block with END + # which is the last before the data block. + + while (read (in, Memc[hb], FITS_BLOCK_CHARS) != EOF) { + call miiupk (Memc[hb], buf[ip], FITS_BLOCK_BYTES, + MII_BYTE,TY_CHAR) + + # Look for the END card + do i = 0, 35 { + j = ip + i*LEN_CARD + if (buf[j] == 'E') { + if (strncmp (buf[j], "END ", 8) == 0) + end_card = true + } + } + nblks = nblks + 1 + if (end_card) + break + call miipak (buf[ip], Memc[hb], FITS_BLOCK_BYTES, + TY_CHAR, MII_BYTE) + call write (out, Memc[hb], FITS_BLOCK_CHARS) + ip = ip + FITS_BLOCK_BYTES + + # If the header is really big we can run out of + # buffer space. Revert back to the beginning. + + if (ip > bufsize) { + ip = 1 + nblks = 1 + } + } + } + + hsize = nblks * 36 * LEN_CARD + + # We are at the beginning of the pixel area. + poffset = note (in) + + # Get the beginnning of the next header. + hoffset = poffset + totpix + + call sfree (sp) +end + + +# FXF_XN_DECODE_BLK1 -- Function that return true if the 1st block of a header +# contains the END card. The size of the pixel are is also returned. + +bool procedure fxf_xn_decode_blk1 (buf, datalen) + +char buf[ARB] #I header data buffer +int datalen #O length of data area in chars + +char card[LEN_CARD] +int totpix, nbytes, index, k, i, pcount, bitpix, naxis, ip +int len_axis[7] +int fxf_ctype() +bool end_card +errchk syserr, syserrs + +begin + # Read successive lines of the 1st header block + pcount = 0 + + end_card = false + do k = 0, 35 { + ip = k*LEN_CARD + 1 + + # Copy into a one line buffer, we need to EOS mark. + call strcpy (buf[ip], card, LEN_CARD) + switch (fxf_ctype (card, index)) { + case KW_END: + end_card = true + break + case KW_PCOUNT: + call fxf_geti (card, pcount) + case KW_BITPIX: + call fxf_geti (card, bitpix) + case KW_NAXIS: + if (index == 0) { + call fxf_geti (card, naxis) + if (naxis < 0 ) + call syserr (SYS_FXFRFBNAXIS) + } else + call fxf_geti (card, len_axis[index]) + default: + ; + } + } + + # Calculate the length of the data area of the current extension, + # measured in SPP chars and rounded up to an integral number of FITS + # logical blocks. + + if (naxis != 0) { + totpix = len_axis[1] + do i = 2, naxis + totpix = totpix * len_axis[i] + + # Compute the size of the data area (pixel matrix plus PCOUNT) + # in bytes. Be careful not to overflow a 32 bit integer. + + nbytes = (totpix + pcount) * (abs(bitpix) / NBITS_BYTE) + + # Round up to fill the final 2880 byte FITS logical block. + nbytes = ((nbytes + 2880-1) / 2880) * 2880 + + datalen = nbytes / SZB_CHAR + + } else + datalen = 0 + + return (end_card) +end + + +# FXF_XADDL -- Algorithm to find the number of blank cards stored in the +# input buffer. This is the number from the end of the buffer up to the +# last non blank card (excluding the END card). The function returns the +# number of extra header cards (in multiple of 36) that is necessary to +# add to the current header. + +int procedure fxf_xaddl (hd, ncua, nlines) + +pointer hd #U header area pointer +int ncua #I number of characters in the user area +int nlines #I minimum number of header lines to be added + +int ip, nbc, k, ncards, nkeyw +int strncmp() + +begin + # Go to the end of buffer and get last line pointer + ip = hd + ncua - LEN_CARD + + # See if line is blank. + nbc = 0 + while (ip > hd) { + # Check for nonblank card + do k = 0, LEN_CARD-1 + if (Memc[ip+k] != ' ') + break + + # Since we are counting from the bottom, the first keyword + # (except END) would end counting. + + if (k != LEN_CARD && k != 0) # nonblank keyw card reached + break + else if (k == 0) { + # Just bypass END and continue looking for blank cards + if (strncmp ("END ", Memc[ip], 8) == 0) { + # Clear this card as it will be written at the + # end of the output header. + call amovkc (" ", Memc[ip], LEN_CARD) + ip = ip - LEN_CARD + next + } else + break + } else + nbc = nbc + 1 + ip = ip - LEN_CARD + } + + # Calculate the number of keywords right before the last blank + # card and right after the last non-blank keyword, excluding the + # END card + + nkeyw = (ip-hd)/80 + 1 + + ncards = ncua / LEN_CARD + + # Calculate the complement with respect to 36 + ncards = ((ncards + 35)/36)*36 - ncards + nbc = nbc + ncards + + + if (nbc < nlines) { + # Lets add nlines-nbc cards to the header + ncards = nlines - nbc + + # Adjust to a 36 cards boundary. + ncards = 36 - mod (ncards, 36) + ncards + } else + ncards = 0 + + return (ncards) +end |