Terminal Equipment (TE); Processable data; File transfer

RE/TE-01058

Terminalska oprema (TE) – Podatki, ki jih je mogoče obdelati – Prenos datotek

General Information

Status
Published
Publication Date
23-Nov-1995
Current Stage
12 - Completion
Due Date
03-Nov-1995
Completion Date
24-Nov-1995

Buy Standard

Amendment
ETS 300 075:2003/A1 E2:2003
English language
34 pages
sale 10% off
Preview
sale 10% off
Preview
e-Library read for
1 day

Standards Content (Sample)

SLOVENSKI STANDARD
SIST ETS 300 075:2003/A1 E2:2003
01-december-2003
7HUPLQDOVNDRSUHPD 7( ±3RGDWNLNLMLKMHPRJRþHREGHODWL±3UHQRVGDWRWHN
Terminal Equipment (TE); Processable data; File transfer
Ta slovenski standard je istoveten z: ETS 300 075/A1 Edition 2
ICS:
33.160.99 Druga avdio, video in Other audio, video and
avdiovizuelna oprema audiovisual equipment
35.180 Terminalska in druga IT Terminal and other
periferna oprema IT peripheral equipment
SIST ETS 300 075:2003/A1 E2:2003 en
2003-01.Slovenski inštitut za standardizacijo. Razmnoževanje celote ali delov tega standarda ni dovoljeno.

---------------------- Page: 1 ----------------------

SIST ETS 300 075:2003/A1 E2:2003

---------------------- Page: 2 ----------------------

SIST ETS 300 075:2003/A1 E2:2003
ETS 300 075
AMENDMENT A1
November 1995
Source: ETSI TC-TE Reference: RE/TE-01058
ICS: 33.040
processable data, file transfer
Key words:
This amendment A1 modifies
the European Telecommunication Standard ETS 300 075 (1994) - Second Edition
Terminal Equipment (TE);
Processable data;
File transfer
ETSI
European Telecommunications Standards Institute
ETSI Secretariat
F-06921 Sophia Antipolis CEDEX - FRANCE
Postal address:
650 Route des Lucioles - Sophia Antipolis - Valbonne - FRANCE
Office address:
c=fr, a=atlas, p=etsi, s=secretariat - secretariat@etsi.fr
X.400: Internet:
Tel.: +33 92 94 42 00 - Fax: +33 93 65 47 16
Copyright Notification: No part may be reproduced except as authorized by written permission. The copyright and the
foregoing restriction extend to reproduction in all media.
© European Telecommunications Standards Institute 1995. All rights reserved.
New presentation - see History box

---------------------- Page: 3 ----------------------

SIST ETS 300 075:2003/A1 E2:2003
Page 2
ETS 300 075: February 1994/A1: November 1995
Whilst every care has been taken in the preparation and publication of this document, errors in content,
typographical or otherwise, may occur. If you have comments concerning its accuracy, please write to
"ETSI Editing and Committee Support Dept." at the address shown on the title page.

---------------------- Page: 4 ----------------------

SIST ETS 300 075:2003/A1 E2:2003
Page 3
ETS 300 075: February 1994/A1: November 1995
Foreword
This amendment to ETS 300 075 (1994), second edition, has been produced by the Terminal Equipment
(TE) Technical Committee of the European Telecommunications Standards Institute (ETSI).
Transposition dates
Date of adoption of this ETS: 13 October 1995
Date of latest announcement of this ETS (doa): 29 February 1996
Date of latest publication of new National Standard
or endorsement of this ETS (dop/e): 31 August 1996
Date of withdrawal of any conflicting National Standard (dow): 31 August 1996
Amendments
The amendments are as follows:
Page 15, clause 2, normative references. Add CCITT Recommendation T.51 (1992) as reference [8].
[8] CCITT Recommendation T.51 (1992): "Latin based coded character sets for
telematic services".
Page 54, subclause 5.5.1.28. For applications that display the progress of the file transfer and
calculate the remaining time, it would be helpful to know the exact amount of physical data to
transfer. This can be achieved by an optional attribute in the file header. Subclause 5.5.1.28 is to
be renumbered as subclause 5.5.1.29 with the following being inserted:
5.5.1.28 Length of file during transmission
This attribute indicates the size in bytes of the file content in compressed form. If the file is transferred in
uncompressed form, this parameter, when present, shall be set equal to the file length parameter.

---------------------- Page: 5 ----------------------

SIST ETS 300 075:2003/A1 E2:2003
Page 4
ETS 300 075: February 1994/A1: November 1995
Modify table 2 in the re-numbered subclause 5.5.1.29 (status of file attributes) as follows:
Table 2
File Attributes Application Default Value
Telesoftware Printer
File type O O Text file
Execution order O - Don't care
Transfer name O O No
Filename O O No
Date of last modification O O No
File length O O No
Destination code O - Don't care
File coding O O Depends on file type
Destination name O - No
Cost O O No
User field/Application reference O O No
Load address (abs.) O - No
Execute address (abs.) O - No
Execute address (rel.) O - No
Compression mode O O No compression
Device O O Don't care
File checksum O O No
Author name O O No
Future file length O O No
Permitted actions O O No
Legal qualification O O No
Creation O O No
Last read access O O No
Identity of the last modifier O O No
Identity of the last reader O O No
Recipient O O No
Telematic file transfer version O O No
Length of file during transmission O O No
O: Optional
-: Irrelevant
NOTE: Other attributes may be added to take into account the auxiliary device application
requirements.
Page 54, subclause 5.6.1, third and fifth paragraphs, replace the reference to subclause 5.5.1.17 by
subclause 5.5.1.29 to read as follows:
All the attributes listed in subclause 5.5.1.29 may be used to characterize a file involved in a telesoftware
application.
The attributes listed in subclause 5.5.1.29 may be used to characterize a file involved in a printer device
application.

---------------------- Page: 6 ----------------------

SIST ETS 300 075:2003/A1 E2:2003
Page 5
ETS 300 075: February 1994/A1: November 1995
Page 66, subclause 6.2.5.1, tenth line, delete the bullet item "user abort of the access regime;" to
read as shown below.
6.2.5.1 Content of the T-End-Access TDU and the associated response
T-End-Access
Reason
User data
T-Response-positive
User data
The use of the parameters is described in the service definition.
The Reason parameter in T-End-Access takes one of the following values:
- termination of the access regime requested by the service user:
- reason not specified (default value);
- insufficient primitives handled;
- other reason (this last value may be followed by a string of no more than 62 displayable
characters).
Page 78, subclause 7.1.1.1, amend the sentence to replace "table 5" by "table 4":
The first byte of a TDU identifies the TDU according to the coding in table 4.
Page 78, subclause 7.1.1.3, amend the first bullet point to replace "table 6" by "table 5":
- Parameter Identifier field (PI): a single byte identifying the parameter. The coding of PIs is
specified in table 5;
Page 80, subclause 7.1.2.1.2, amend the final sentence on page 81 to read:
A T-associate response coded on one byte indicates that only the Basic kernel is supported by the
receiver.

---------------------- Page: 7 ----------------------

SIST ETS 300 075:2003/A1 E2:2003
Page 6
ETS 300 075: February 1994/A1: November 1995
Page 94, table 6, subclause 7.3.2, modify the table to read as follows:
Table 6: Coding of file attributes
Attribute PI
File type 2/0
Execution order 2/1
Transfer name 2/2
File name 2/3
Date 2/4
File length 2/5
Destination code 2/6
File coding 2/7
Destination name 2/8
Cost 2/9
User field/Application reference 2/10
Load address 2/11
Execute address (absolute) 2/12
Execute address (relative) 2/13
Compression mode 2/14
Device 2/15
File checksum 3/0
Author name 3/1
Future file length 3/2
Permitted actions 3/3
Legal qualification 3/4
Creation 3/5
Last read access 3/6
Identity of the last modifier 3/7
Identity of the last reader 3/8
Recipient 3/9
Telematic file transfer version 3/10
Length of file during transmission 3/11
Page 96, subclause 7.3.2.8. The possible use of the file transfer protocol outside the Videotex area
requires the identification of new contents and their encodings. One of them is the facsimile
encoding according to ITU-T Recommendations T.4 and T.6.
For this purpose, extend the text file list in subclause 7.3.2.8 as follows:
Text file: 5/0 other code,
5/1 As for 3/1 above (default value),
5/2 Videotex code profile 2 (as defined by ETS 300 072 [2]),
5/3 Videotex code profile 1 (as defined by ETS 300 072 [2]),
5/4 Videotex code profile 3 (as defined by ETS 300 072 [2]),
5/7 geometric,
5/6 photographic,
5/7 sound.
facsimile coded file: 6/0 ITU-T Recommendation T.4 encoding schemes,
6/1 ITU-T Recommendation T.6 encoding schemes.

---------------------- Page: 8 ----------------------

SIST ETS 300 075:2003/A1 E2:2003
Page 7
ETS 300 075: February 1994/A1: November 1995
Subsequent bytes, if present, for "6/0" and "6/1" values are coded as follows:
The following byte identifies the compression mode:
2/0 no compression,
2/1 monodimensional compression -T.4 (default),
2/2 bidimensional compression with K=2 -T.4,
2/3 bidimensional compression with K=4 -T.4,
2/4 bidimensional compression with K=infinite -T.6.
The following byte identifies the paper length:
2/10 ISO A4 (default),
2/11 ISO B4,
2/12 ISO A3,
2/13 unlimited.
The following byte identifies the horizontal resolution:
3/0 R8 = 1 728 pels/215 mm for ISO A4 (default),
3/1 R8 = 2 048 pels/255 mm for ISO B4,
3/2 R8 = 2 432 pels/303 mm for ISO A3,
3/3 R16 = 3 456 pels/215 mm for ISO A4 (default),
3/4 R16 = 4 096 pels/255 mm for ISO B4,
3/5 R16 = 4 864 pels/303 mm for ISO A3.
The following byte identifies the vertical resolution:
4/0 3,85 lines/mm,
4/1 7,7 lines/mm (default),
4/2 15,4 lines/mm.
The following byte identifies inch-based resolutions:
5/0 200*200 pels/25,4 mm,
5/1 240*240 pels/25,4 mm,
5/2 300*300 pels/25,4 mm,
5/1 400*400 pels/25,4 mm.
Page 101, insert the following new subclause 7.3.2.28:
7.3.2.28 Length of the file during transmission
PI compressed file length = 3/11
LI = n < 9
PV = n bytes
The value is a variable length parameter in which the actual number of bytes in the compressed file (the
file length after performing the compression algorithm) is coded in an absolute binary form using all eight
bits of each byte. If the parameter is coded in more than one byte, the first byte to be transmitted
contains the most significant bits.

---------------------- Page: 9 ----------------------

SIST ETS 300 075:2003/A1 E2:2003
Page 8
ETS 300 075: February 1994/A1: November 1995
Page 106, final paragraph of subclause 7.4.3, modify the text to read as follows:
An elementary word is a byte sequence of no more than 12 bytes. Each byte can take any value according
to CCITT Recommendation T.51 [7] in the range 2/1 and 7/14 excepted 2/8, 2/9, 2/11 and 2/15, moreover
this word cannot contain more than one byte 2/10 (displayed "*").
Page 106, subclause 7.4.4, re-name the title as follows:
7.4.4 Designation in T-load, T-Save, T-Rename, T-Delete and NewName in T-Rename

---------------------- Page: 10 ----------------------

SIST ETS 300 075:2003/A1 E2:2003
Page 9
ETS 300 075: February 1994/A1: November 1995
Page 126, annex A, delete the current text and replace with the following:
Annex A (informative): A compression algorithm
This compression is based on two compression algorithms named LZSS and adaptive Huffman
compression. The LZSS is a dictionary based algorithm, and Huffman reduces the most frequent
characters.
The following set of files is an example
- Lzhuf.c , compression algorithm
- Huftbl.c, huffman Tables
- Crc32.c, CRC calculation
- all.h, general.h, ansi.h, include files
/*===========================================================================*
* lzhuf.c                                  *
*   LZSS and adaptive Huffman data compression              *
*===========================================================================*/
/*
* written by Haruyasu Yoshizaki 11/20/1988
* some minor changes 4/6/1989
* comments translated by Haruhiko Okumura 4/7/1989
* modified for Btx-FIF by InfoTeSys GmhH 1991-11-04
*   - use malloc() instead of huge static areas
*   - files have to be opened outside of this module
*   - FCS-check included
*   - length field "long(Filesize)" has been removed from file
* modified by Orsenna 15/06/1994
*   - comments added
*   - some minor changes
*/
/*==============*
* HEADER FILES *
*==============*/
#include
#include
#include
#include "all.h"
/*===========*
* CONSTANTS *
*===========*/
#ifndef EXIT_FAILURE
#define EXIT_FAILURE  0
#define EXIT_SUCCESS  1
#endif
#ifndef SEEK_SET
#define SEEK_SET  0
#define SEEK_END  2
#endif
/*
* DIC_BIT_COUNT is the number of bits to encode a position in the dictionary
*/
#define DIC_BIT_COUNT  12
/*
* The buffer size is equal to 1 << 12 = 4096
*/
#define WINDOW_SIZE   (1 << DIC_BIT_COUNT)

---------------------- Page: 11 ----------------------

SIST ETS 300 075:2003/A1 E2:2003
Page 10
ETS 300 075: February 1994/A1: November 1995
/*
* Lookahead buffer size (needs 6 bits) ; used for length encoding so
* LENGTH_BIT_COUNT = 6
*/
#define LOOK_AHEAD_SIZE 60
/*
* Threshold is a number to see from which length it's better to encode
* with an index/length (12+6=18bits) or only a separate character (8 bits).
* THRESHOLD = ((1+DIC_BIT_COUNT+LENGTH_BIT_COUNT)/9)
* The length must be > to THRESHOLD to encode with an index/length.
*/
#define THRESHOLD    2
/*
* NIL is used by the leafs of the tree.
*/
#define NIL       WINDOW_SIZE
#define TEXT_BUF_LEN  (WINDOW_SIZE + LOOK_AHEAD_SIZE - 1)
/*
* kinds of characters (character code = 0.N_CHAR-1) :
* # 256 'standard' codes (0.255)
* # LOOK_AHEAD_SIZE is used for length codes
* # - THRESHOLD because we start encoding length codes from THRESHOLD
*/
#define N_CHAR     (256 - THRESHOLD + LOOK_AHEAD_SIZE)
/*
* Size of table
*/
#define TABLE_SIZE   (N_CHAR * 2 - 1)
/*
* Position of root
*/
#define ROOT_NODE    (TABLE_SIZE - 1)
/*
* MAX_FREQ is used to update tree when the root frequency comes to
* this value.
*/
#define MAX_FREQ    0x8000
/*==================*
* STATIC VARIABLES *
*==================*/
static FILE *inFile, *outFile;
static int32 inpSize, outSize;
static char  writeError[] = "Can't write.";
static uint8 *textBuffer;
static uint16 matchPosition;   /* best position */
static int   matchLength;    /* best length  */
static int16 *leftSon;      /* [WINDOW_SIZE + 1]; */
/*
* [WINDOW_SIZE+1.WINDOW_SIZE + 257 - 1] is used to conserve roots
*/
static int16 *rightSon;      /* [WINDOW_SIZE + 257]; */
static int16 *dad;        /* [WINDOW_SIZE + 1];  */
/*=======================*
* STRUCTURE DEFINITIONS *
*=======================*/
/*
* You can change the input and output buffer size, it's faster with big
* buffer size.
*/
typedef struct LzhEnvStruct {
  uint8  inputBuffer[2048];         /* input buffer : 2Ko */
  int   inputPosition;
  int   inputMax;

---------------------- Page: 12 ----------------------

SIST ETS 300 075:2003/A1 E2:2003
Page 11
ETS 300 075: February 1994/A1: November 1995
  uint8  outputBuffer[1024];        /* output buffer : 1Ko */
  int   outputPosition;
  int   outputMax;
  uint16  freq[TABLE_SIZE + 1];       /* frequency table */
  /*
  * pointers to parent nodes, except for the
  * elements [TABLE_SIZE.TABLE_SIZE + N_CHAR - 1] which are used to get
  * the positions of leaves corresponding to the codes.
  */
  int   parent[TABLE_SIZE + N_CHAR];
  /*
   * pointers to child nodes (son[], son[] + 1)
   */
  int   son[TABLE_SIZE];
} LzhEnv;
static LzhEnv *lzhEnv;
/*===============================*
* INTERNAL PROCEDURE prototypes *
*===============================*/
static void   Error _ANSI_ARGS_((char *message));
static int16  InputByte _ANSI_ARGS_((void));
static int   OutputByte _ANSI_ARGS_((int16 byte_to_output));
static void   InitTree _ANSI_ARGS_((void));
static void   InsertNode _ANSI_ARGS_((int16 new_node));
static void   DeleteNode _ANSI_ARGS_((int p));
static int16  GetBit _ANSI_ARGS_((void));
static int16  GetByte _ANSI_ARGS_((void));
static void   PutCode _ANSI_ARGS_((int16 l, uint16 c));
static void   StartHuffman _ANSI_ARGS_((void));
static void   Reconst _ANSI_ARGS_((void));
static void   UpDate _ANSI_ARGS_((int c));
static void   EncodeChar _ANSI_ARGS_((unsigned c));
static void   EncodePosition _ANSI_ARGS_((unsigned position));
static void   EncodeEnd _ANSI_ARGS_((void));
static int   DecodeChar _ANSI_ARGS_((void));
static int   DecodePosition _ANSI_ARGS_((void));
static void   LzhEncode _ANSI_ARGS_((uint32 *encode_crc_32));
static void   LzhDecode _ANSI_ARGS_((long filesize, uint32 *decode_crc_32));
/*===========================================================================*
* Error
*   An error handler.
* RETURNS:   nothing
*===========================================================================*/
static void
Error(message)
  char *message;
{
  printf("\r\n%s\n", message);
  exit(EXIT_FAILURE);
}
/*===========================================================================*
* InputByte
*   Input a byte from a file.
* RETURNS:   a byte
*===========================================================================*/
static int16
InputByte()
{
  if (lzhEnv->inputPosition >= lzhEnv->inputMax) {
    lzhEnv->inputMax = fread((uint8 *) lzhEnv->inputBuffer, 1,
                 lzhEnv->inputMax, inFile);
    if (lzhEnv->inputMax == 0) {
      return EOF;

---------------------- Page: 13 ----------------------

SIST ETS 300 075:2003/A1 E2:2003
Page 12
ETS 300 075: February 1994/A1: November 1995
    }
    lzhEnv->inputPosition = 0;
    inpSize += lzhEnv->inputMax;
    printf("\r %6ld\r", inpSize);
  }
  return(lzhEnv->inputBuffer[lzhEnv->inputPosition++]);
}
/*===========================================================================*
* OutputByte
*   Output a byte to a file.
* RETURNS:   1 if no error
*===========================================================================*/
static int
OutputByte(byte_to_output)
  int16 byte_to_output;
{
  if (lzhEnv->outputPosition == lzhEnv->outputMax) {
    lzhEnv->outputPosition = fwrite((uint8 *) lzhEnv->outputBuffer,
                   1, lzhEnv->outputPosition, outFile);
    outSize += lzhEnv->outputPosition;
    lzhEnv->outputPosition = 0;
    printf("\r\t\t\t\t\t %6ld\r", outSize);
  }
  lzhEnv->outputBuffer[lzhEnv->outputPosition++] = (uint8) byte_to_output;
  return 1;
}
/*===========================================================================*
* InitTree
*   Initialize LZSS tree.
* RETURNS:   nothing
*============================================================================*/
static void
InitTree()
{
  register int i;
  /*
   * [WINDOW_SIZE+1.WINDOW_SIZE + 256] is used to conserve roots.
   */
  for (i = WINDOW_SIZE + 1; i <= WINDOW_SIZE + 256; i++) {
    rightSon[i] = NIL;
  }
  for (i = 0; i < WINDOW_SIZE; i++) {
    dad[i] = NIL;       /* node */
  }
}
/*===========================================================================*
* InsertNode
*   Insert a node to tree; find the best match.
* RETURNS:   nothing
*===========================================================================*/
static void
InsertNode(new_node)
  register int16 new_node;
{
  register int16 p;
  int       i, cmp;
  uint8     *key;
  unsigned    c;
  cmp = 1;
  /*
   * Key is a pointer to the current string.
   */
  key = &textBuffer[new_node];

---------------------- Page: 14 ----------------------

SIST ETS 300 075:2003/A1 E2:2003
Page 13
ETS 300 075: February 1994/A1: November 1995
  /*
   * To start, p is a root used to find where this character (key[0])
   * already appared in the dictionary. We use WINDOW_SIZE + 1 + key[0]
   * because rightSon from WINDOW_SIZE + 1 is used to conserve roots.
   */
  p  = WINDOW_SIZE + 1 + (int16) key[0];
  rightSon[new_node] = NIL;
  leftSon[new_node] = NIL;
  matchLength = 0;
  for ( ; ; ) {
    /*
     * If the difference between the current string and the best string
     * found (for the moment) is greater than 0, we seek for another
     * string in checking rightSon.
     */
    if (cmp >= 0) {
      if (rightSon[p] != NIL) {
        p = rightSon[p];
      } else {           /* add a node */
        /*
         *   p (dad[new_node])
         *   |
         *   ---- new_node (rightSon[p])
         */
        rightSon[p] = new_node;
        dad[new_node] = p;
        return;
      }
    } else {
      if (leftSon[p] != NIL) {
        p = leftSon[p];
      } else {
        leftSon[p] = new_node;
        dad[new_node] = p;
        return;
      }
    }
    for (i = 1; i < LOOK_AHEAD_SIZE; i++) {
      /*
       * Compare the current string with the position where this
       * string already appared.
       * key is the current string, p is the better position.
       */
      if ((cmp = key[i] - textBuffer[p + i]) != 0) {
        break;  /* Exit for(.) if not equal char */
      }
    }
    /*
     * i is the corresponding length find from the current string
     */
    if (i > THRESHOLD) {
      if (i > matchLength) {  /* i is > to the current best length ? */
        /*
         * matchPosition is the position difference from the current
         * character.
         */
        matchPosition = (uint16) (((new_node - p) &
                      (WINDOW_SIZE - 1)) - 1);
        if ((matchLength = i) >= LOOK_AHEAD_SIZE) {
          break;
        }
      }
      if (i == matchLength) { /* i is = to the current best length */

---------------------- Page: 15 ----------------------

SIST ETS 300 075:2003/A1 E2:2003
Page 14
ETS 300 075: February 1994/A1: November 1995
        if ((c = ((new_node - p) & (WINDOW_SIZE - 1)) - 1)
             < matchPosition) {
          matchPosition = (uint16) c;
        }
      }
    }
  }
  /*
   * Set the new node equal to the node of the best position found.
   */
  i = dad[p];
  dad[new_node]   = (uint16) i;
  leftSon[new_node] = leftSon[p];
  rightSon[new_node] = rightSon[p];
  dad[leftSon[p]]  = new_node;
  dad[rightSon[p]]  = new_node;
  if (rightSon[i] == p) {   /* if p is on the right */
    rightSon[i] = new_node;
  } else {          /* p is on the left */
    leftSon[i] = new_node;
  }
  /*
   * remove the old node p (best position found)
   */
  dad[p] = NIL;
}
/*===========================================================================*
* DeleteNode
*   Remove a node from tree.
* RETURNS:  nothing
*===========================================================================*/
static void
DeleteNode(p)
  register int p;
{
  register int replacement;
  if (dad[p] == NIL) {
    return;           /* not registered ! */
  }
  if (rightSon[p] == NIL) {
    /*
     * Right link is null so we'll pull the non-null (left) link up one
     * to replace the existing link.
     */
    replacement = leftSon[p];
  } else {
    if (leftSon[p] == NIL) {
      /*
       * Left link is null so we'll pull the non-null (right) link
       * up one to replace the existing link.
       */
      replacement = rightSon[p];
    } else {
      /*
       * Both links exist, we instead delete the next link in order,
       * which is guaranteed to have a null link, then replace the node
       * to be deleted with the next link.
       */
      replacement = leftSon[p];
      if (rightSon[replacement] != NIL) {
        do {
          replacement = rightSon[replacement];
        } while (rightSon[replacement] != NIL);

---------------------- Page: 16 ----------------------

SIST ETS 300 075:2003/A1 E2:2003
Page 15
ETS 300 075: February 1994/A1: November 1995
        rightSon[dad[replacement]] = leftSon[replacement];
        dad[leftSon[replacement]] = dad[replacement];
        leftSon[replacement]    = leftSon[p];
        dad[leftSon[p]]      = (int16) replacement;
      }
      rightSon[replacement]   = rightSon[p];
      dad[rightSon[p]]      = (int16) replacement;
    }
  }
  dad[replacement] = dad[p];
  if (rightSon[dad[p]] == p) {  /* p is a right child */
    rightSon[dad[p]] = (int16) replacement;
  } else {            /* p is a left child */
    leftSon[dad[p]] = (int16) replacement;
  }
  dad[p] = NIL;
}
static uint16 getbuf = 0;
static int16 getlen = 0;
/*===========================================================================*
* GetBit
*   Get one bit.
* RETURNS:   the bit needed !
*===========================================================================*/
static int16
GetBit()
{
  register int16 i, j;
  j = getlen;
  while (j <= 8) {
    if ((i = InputByte()) == EOF) {
      i = 0;
    }
    getbuf |= (i << (8 - j));
    j += 8;
  }
  i = getbuf;
  getbuf <<= 1;
  getlen = --j;
  return((int16) (i < 0));
}
/*===========================================================================*
* GetByte
*   Get one byte.
* RETURNS:   a byte
*===========================================================================*/
static int16
GetByte()
{
  register uint16 i;
  register int16 j;
  j = getlen;
  while (j <= 8) {
    if ((i = InputByte()) == (unsigned) EOF) {
      i = 0;
    }
    getbuf |= i << (8 - j);
    j += 8;
  }
  i = getbuf;
  getbuf <<= 8;
  getlen = (int16) (j - 8);
  return(i >> 8);

---------------------- Page: 17 ----------------------

SIST ETS 300 075:2003/A1 E2:2003
Page 16
ETS 300 075: February 1994/A1: November 1995
}
static uint16 putbuf = 0;
static int16 putlen = 0;
/*===========================================================================*
* PutCode
*   Output a code.
* RETURNS:   nothing
*===========================================================================*/
static void
PutCode(l, c)
  int16 l;         /* length */
  register uint16 c;    /* code  */
{
  register int16 j;
  j = putlen;
  putbuf |= c >> j;
  if ((j += l) >= 8) {
    if (! OutputByte((int16) (putbuf >> 8))) {  /* HIBYTE putbuf */
      Error(writeError);
    }
    if ((j -= 8) >= 8) {
      if (! OutputByte((int16) putbuf)) {   /* LOBYTE putbuf */
        Error(writeError);
      }
      j    -= 8;
      putbuf  = (uint16) (c << (l - j));
    } else {
      putbuf <<= 8;
    }
  }
  putlen = j;
}
/*===========================================================================*
* StartHuffman
*   Initialization of Huffman's tree.
* RETURNS:   nothing
*===========================================================================*/
static void
StartHuffman()
{
  register int i, j;
  leftSon   = calloc(1, (WINDOW_SIZE +  1) * sizeof(int16));
  rightSon  = calloc(1, (WINDOW_SIZE + 257) * sizeof(int16));
  dad     = calloc(1, (WINDOW_SIZE +  1) * sizeof(int16));
  textBuffer = calloc(1, TEXT_BUF_LEN);
  memset(textBuffer, ' ', (WINDOW_SIZE - LOOK_AHEAD_SIZE));
  lzhEnv   = calloc(1, sizeof(struct LzhEnvStruct));
  lzhEnv->inputMax  = lzhEnv->inputPosition = sizeof(lzhEnv->inputBuffer);
  lzhEnv->outputMax = sizeof(lzhEnv->outputBuffer);
  getbuf = getlen = putbuf = putlen = 0;
  matchLength  = 0;
  matchPosition = 0;
  inpSize = outSize = 0;
  for (i = 0; i < N_CHAR; i++) {
    lzhEnv->freq[i]        = 1;
    lzhEnv->son[i]         = i + TABLE_SIZE;
    lzhEnv->parent[i + TABLE_SIZE] = i;
  }
  i = 0;
  j = N_CHAR;
  while (j <= ROOT_NODE) {
    lzhEnv->freq[j] = lzhEnv->freq[i] + lzhEnv->freq[i + 1];
    lzhEnv->son[j] = i;

---------------------- Page: 18 ----------------------

SIST ETS 300 075:2003/A1 E2:2003
Page 17
ETS 300 075: February 1994/A1: November 1995
    lzhEnv->parent[i] = lzhEnv->parent[i + 1] = j;
    i += 2;
    j++;
  }
  lzhEnv->freq[TABLE_SIZE] = 0xffff;
  lzhEnv->parent[ROOT_NODE] = 0;
}
/*===========================================================================*
* Reconst
*   Reconstruction of tree (frequencies values are too high).
* RETURNS:   nothing
*===========================================================================*/
static void
Reconst()
{
  register int i, k, j;
  uint16 f, l;
  /*
   * Collect leaf nodes in the first half of the table and replace
   * the freq by (freq + 1) / 2.
   */
  for (i = k = 0; i < TABLE_SIZE; ++i) {
    if (lzhEnv->son[i] >= TABLE_SIZE) {
      lzhEnv->freq[k] = (lzhEnv->freq[i] + 1) / 2;
      lzhEnv->son[k] = lzhEnv->son[i];
      k++;
    }
  }
  /*
   * Begin constructing tree by connecting sons.
   */
  for (i = 0, j = N_CHAR; j < TABLE_SIZE; i += 2, j++) {
    /*
     * Build new node by adding freqs
     */
    k = i + 1;
    f = lzhEnv->freq[j] = lzhEnv->freq[i] + lzhEnv->freq[k];
    /*
     * Find the position in node list.
     */
    for (k = j - 1; f < lzhEnv->freq[k]; k--);
    k++;
    l = (uint16) ((j - k) * 2);
    /* With some UNIX systems, replace memmove() by memcpy() */
    memmove(&lzhEnv->freq[k + 1], &lzhEnv->freq[k], l);
    lzhEnv->freq[k] = f;
    memmove(&lzhEnv->son[k + 1], &lzhEnv->son[k], l);
    lzhEnv->son[k] = i;
  }
  /*
   * Connect parent.
   */

...

Questions, Comments and Discussion

Ask us and Technical Secretary will try to provide an answer. You can facilitate discussion about the standard in here.