1 /*************************************************************
2 Copyright (C) 1990, 1991, 1993 Andy C. Hung, all rights reserved.
3 PUBLIC DOMAIN LICENSE: Stanford University Portable Video Research
4 Group. If you use this software, you agree to the following: This
5 program package is purely experimental, and is licensed "as is".
6 Permission is granted to use, modify, and distribute this program
7 without charge for any purpose, provided this license/ disclaimer
8 notice appears in the copies.  No warranty or maintenance is given,
9 either expressed or implied.  In no event shall the author(s) be
10 liable to you or a third party for any special, incidental,
11 consequential, or other damages, arising out of the use or inability
12 to use the program for any purpose (or the loss of data), even if we
13 have been advised of such possibilities.  Any public reference or
14 advertisement of this source code should refer to it as the Portable
15 Video Research Group (PVRG) code, and not by any author(s) (or
16 Stanford University) name.
17 *************************************************************/
18 %option yylineno
19 %{
20 
21 /*LABEL lexer.c */
22 
23 /*
24  * flex command was run this way:
25  *
26  *  $ lex -olexer.c lexer.l
27  */
28 
29 /* We do not care of interactive mode */
30 #define YY_NEVER_INTERACTIVE 1
31 #define YY_NO_UNPUT 1
32 
33 /* Do not include unistd.h in generated source. */
34 #define YY_NO_UNISTD_H
35 
36 /* Skip declaring this function.  It is a macro.  */
37 #define YY_SKIP_YYWRAP
38 
39 /* Redefine the yywrap so that we don't have
40    to worry about lex library */
41 
42 # define yywrap() (1)
43 
44 static char *ReservedWords[] = {   /* Token names */
45 "COMPONENT",
46 "SCAN",
47 "QUANTIZATION",
48 "DCSPEC",
49 "ACCUSTOM",
50 "DCCUSTOM",
51 "PRINTSCAN",
52 "PRINTFRAME",
53 "PRINTIMAGE",
54 "OPENSCAN",
55 "ACSPEC",
56 "WRITESCAN",
57 "WRITEFRAME",
58 "WRITESOI",
59 "WRITEQUANTIZATION",
60 "WRITERESYNC",
61 "WRITEHUFFMAN",
62 "FREQUENCY",
63 "ACSEND",
64 "DCSEND",
65 "QSEND",
66 "STREAMNAME",
67 "IMAGEHEIGHT",
68 "IMAGEWIDTH",
69 "RESYNC",
70 "BUFFER",
71 "OPENSTREAM",
72 "CLOSESTREAM",
73 "FRAMEHEIGHT",
74 "FRAMEWIDTH",
75 "CLOSESCAN",
76 "WRITEEOI",
77 "ECHO",
78 "WRITESPECIAL",
79 "WRITEDIRECT",
80 "LUMINANCEDEFAULT",
81 "CHROMINANCEDEFAULT",
82 "ENABLE",
83 "SCANDNL",
84 "WRITEDNL",
85 "AUTO",
86 "EMPTY",
87 ""};
88 
89 #define R_COMPONENT 1           /* Token values mapped to token names */
90 #define R_SCAN 2
91 #define R_QUANTIZATION 3
92 #define R_DCSPEC 4
93 #define R_ACCUSTOM 5
94 #define R_DCCUSTOM 6
95 #define R_PRINTSCAN 7
96 #define R_PRINTFRAME 8
97 #define R_PRINTIMAGE 9
98 #define R_OPENSCAN 10
99 #define R_ACSPEC 11
100 #define R_WRITESCAN 12
101 #define R_WRITEFRAME 13
102 #define R_WRITESOI 14
103 #define R_WRITEQUANTIZATION 15
104 #define R_WRITERESYNC 16
105 #define R_WRITEHUFFMAN 17
106 #define R_FREQUENCY 18
107 #define R_ACSEND 19
108 #define R_DCSEND 20
109 #define R_QSEND 21
110 #define R_STREAMNAME 22
111 #define R_IMAGEHEIGHT 23
112 #define R_IMAGEWIDTH 24
113 #define R_RESYNC 25
114 #define R_BUFFER 26
115 #define R_OPENSTREAM 27
116 #define R_CLOSESTREAM 28
117 #define R_FRAMEHEIGHT 29
118 #define R_FRAMEWIDTH 30
119 #define R_CLOSESCAN 31
120 #define R_WRITEEOI 32
121 #define R_ECHO 33
122 #define R_WRITESPECIAL 34
123 #define R_WRITEDIRECT 35
124 #define R_LUMINANCEDEFAULT 36
125 #define R_CHROMINANCEDEFAULT 37
126 #define R_ENABLE 38
127 #define R_SCANDNL 39
128 #define R_WRITEDNL 40
129 #define R_AUTO 41
130 #define R_EMPTY 42
131 
132 #define R_INTEGER 1000      /* Special TYPES for tokens */
133 #define R_LBRACKET 1001
134 #define R_RBRACKET 1002
135 #define R_ID 1003
136 #define R_STRING 1004
137 
138 int CommentDepth = 0;  /* depth of comment nesting */
139 int yyint=0;           /* Return value for integers */
140 int LexDebug=0;        /* Status of lex debugging */
141 
142 #define PRIME 211
143 #define EOS '\0'
144 
145 #define MakeStructure(S) (S *) malloc(sizeof(S))
146 #define InsertLink(link,list){\
147 if(!list){list=link;}else{link->next=list;list=link;}}
148 
149 #define LINK struct link_def
150 struct id {         /* Default id structure */
151   char *name;       /* Key */
152   int tokentype;    /* Token type */
153   int count;        /* Count of # references */
154 };
155 
156 LINK {              /* A link for the hash buckets */
157 struct id *lid;     /* Current id */
158 LINK *next;         /* Pointer to next id */
159 };
160 
161 /*PUBLIC*/
162 
163 extern void initparser();
164 extern void parser();
165 
166 static int hashpjw();
167 static LINK * MakeLink();
168 static struct id * enter();
169 static int getint();
170 static char * getstr();
171 
172 /*PRIVATE*/
173 
174 /*NOPROTO*/
175 
176 %}
177 
178 Delim    [ \t\n]
179 WhiteSpace  {Delim}+
180 Letter      [a-zA-Z]
181 Digit     [0-9]
182 HexDigit    ({Digit}|[a-fA-F])
183 OctalDigit  [0-7]
184 Id    {Letter}({Letter}|{Digit})*
185 DecInteger   {Digit}+
186 HexInteger   0[xX]{HexDigit}+
187 OctInteger   0[oO]{OctalDigit}+
188 HexInteger2  {HexDigit}+[Hh]
189 OctInteger2  {OctalDigit}+[BCObco]
190 CharInteger      '([^\\]|\\([\n^\n]|{OctalDigit}{1,3}))'
191 ScaleFactor  E[-+]?{Digit}+
192 Real1    ({Digit}+"."{Digit}*({ScaleFactor})?)
193 Real2    ({Digit}*"."{Digit}+({ScaleFactor})?)
194 Real3    ({Digit}+{ScaleFactor})
195 Real    {Real1}|{Real2}|{Real3}
196 Operator   (\+|=|\-|#|\*|\<|\>|\/|:=|\<\>|\&|\<=|\.|\>=|\,|\.\.|;|:|\(|\)|\[|\]|\{|\}|\^|\||~)
197 String    \"([^\"]|\\\")*\"
198 
199 %S NORMAL COMMENT
200 %%
201 
202 <NORMAL>{WhiteSpace}  {}
203 
204 <NORMAL>{Id}  {struct id *temp; temp = enter(0,yytext,yyleng);
205      if (LexDebug)
206        {
207          printf("%s : %s (%d)\n",
208           yytext,
209           ((temp->tokentype) ? "RESERVED" : "IDENTIFIER"),
210           temp->count);
211        }
212      if (temp->tokentype)
213        {
214          return(temp->tokentype);
215        }
216      else
217        {
218          return(R_ID);
219        }
220          }
221 <NORMAL>{Real}          {if (LexDebug)
222          {
223            printf("%s : %s\n", yytext, "REAL");
224          }
225            }
226 <NORMAL>{DecInteger}  {if (LexDebug)
227          {
228            printf("%s : %s\n", yytext, "INTEGER");
229          }
230        yyint = atoi(yytext);
231        return(R_INTEGER);}
232 <NORMAL>{HexInteger}  {if (LexDebug)
233          {
234            printf("%s : %s\n", yytext, "(HEX)INTEGER");
235          }
236        yyint = strtol(yytext+2,NULL,16);
237        return(R_INTEGER);}
238 <NORMAL>{HexInteger2}  {if (LexDebug)
239          {
240            printf("%s : %s\n", yytext, "(HEX)INTEGER");
241          }
242        yyint = strtol(yytext,NULL,16);
243        return(R_INTEGER);}
244 <NORMAL>{OctInteger}  {if (LexDebug)
245          {
246            printf("%s : %s\n", yytext, "(OCT)INTEGER");
247          }
248        yyint = strtol(yytext+2,NULL,8);
249        return(R_INTEGER);}
250 <NORMAL>{OctInteger2}  {if (LexDebug)
251          {
252            printf("%s : %s\n", yytext, "(OCT)INTEGER");
253          }
254        yyint = strtol(yytext,NULL,8);
255        return(R_INTEGER);}
256 <NORMAL>{CharInteger}  {if (LexDebug)
257          {
258            printf("%s : %s\n", yytext, "(CHAR)INTEGER");
259          }
260        if (yyleng>4)
261          {
262            yyint = strtol(yytext+2,NULL,8);
263          }
264        else
265          {
266            if (*(yytext+1)=='\\')
267              {
268          switch(*(yytext+2))
269            {
270            case '0':
271              yyint=0;
272              break;
273            case 'b':
274              yyint = 0x8;
275              break;
276            case 'i':
277              yyint = 0x9;
278              break;
279            case 'n':
280              yyint = 0xa;
281              break;
282            case 'v':
283              yyint = 0xb;
284              break;
285            case 'f':
286              yyint = 0xc;
287              break;
288            case 'r':
289              yyint = 0xd;
290              break;
291            default:
292              yyint=(*yytext+2);
293              break;
294            }
295              }
296            else
297              {
298          yyint = *(yytext+1);
299              }
300          }
301        return(R_INTEGER);}
302 <NORMAL>\[          {if (LexDebug)
303          {
304            printf("%s : %s\n", yytext, "LBRACKET");
305          }
306        return(R_LBRACKET);}
307 <NORMAL>\]          {if (LexDebug)
308          {
309            printf("%s : %s\n", yytext, "RBRACKET");
310          }
311        return(R_RBRACKET);}
312 <NORMAL>{Operator}  {if (LexDebug)
313          {
314            printf("%s : %s\n", yytext, "OPERATOR");
315          }
316            }
317 <NORMAL>{String}  {if (LexDebug)
318          {
319            printf("%s : %s\n", yytext, "STRING");
320          }
321        return(R_STRING);}
322 
323 <NORMAL,COMMENT>"/*"  {CommentDepth++; BEGIN COMMENT;}
324 
325 <COMMENT>"*/"    {CommentDepth--;if(!CommentDepth) BEGIN NORMAL;}
326 
327 <NORMAL>.          {
328             /* None of the above rules applicable, so
329              it's a bad symbol. */
330                               printf("Bad input char '%c' on line %d\n",
331                     yytext[0],
332                     yylineno);
333             }
334 
335 <COMMENT>.|\n    {} /*Everything's AOK */
336 
337 %%
338 
339 /*PROTO*/
340 LINK *HashTable[PRIME];  /* My little hash table */
341 
342 /*START*/
343 
344 /*BFUNC
345 
346 initparser() is used to place the Reserved Words into the hash table.
347 It must be called before the parser command is called.
348 
349 EFUNC*/
350 
351 void initparser()
352 {
353   char i,**sptr;
354   BEGIN NORMAL;
355 
356   for(i=1,sptr=ReservedWords;**sptr!='\0';i++,sptr++)
357     {     /* Add Reserved Words */
358       enter(i,*sptr,strlen(*sptr));        /* Put reserved words in */
359     }                                      /* hash table */
360 }
361 
362 #undef BEGIN
363 #undef MakeStructure
364 #include "globals.h"
365 #include "stream.h"
366 #include "tables.h"
367 
368 extern FRAME *CFrame;
369 extern IMAGE *CImage;
370 extern SCAN *CScan;
371 extern int ErrorValue;
372 
373 /*BFUNC
374 
375 hashpjw() returns a hash value for a string input.
376 
377 EFUNC*/
378 
379 static int hashpjw(s)
380      char *s;
381 {
382   BEGIN("hashpjw")
383   char *p;
384   unsigned int g, h;
385   h=0;
386 
387   for(p=s;*p!=EOS;p++)       /* Taken from Aho Sethi Ullman Compilers book. */
388     {
389       h = (h << 4) + *p;
390       if ((g = h&0xf0000000))
391   {
392     h = h ^(g >> 24);
393     h = h ^ g;
394   }
395     }
396   return(h % PRIME);
397 }
398 
399 /*BFUNC
400 
401 MakeLink() is used to construct a link object. The link
402 is used for the hash table construct.
403 
404 EFUNC*/
405 
406 
407 static LINK *MakeLink(tokentype,str,len)
408      int tokentype;
409      char *str;
410      int len;
411 {
412   BEGIN("MakeLink")
413   LINK *temp;
414 
415   if (!(temp = MakeStructure(LINK)))            /* Make link */
416     {
417       WHEREAMI();
418       printf("Cannot make a LINK.\n");
419       exit(ERROR_MEMORY);
420     }
421   if (!(temp->lid = MakeStructure(struct id)))  /* Make id */
422     {
423       printf("Cannot make an id.\n");
424       exit(ERROR_MEMORY);
425     }
426   temp->next = NULL;                            /* Set fields */
427   if (!(temp->lid->name =(char *)calloc(len+1,sizeof(char))))
428     {
429       printf("Cannot make a string space for the link.\n");
430       exit(ERROR_MEMORY);
431     }
432   strcpy(temp->lid->name,str);                 /* Copy key */
433   temp->lid->tokentype = tokentype;
434   temp->lid->count = 1;
435   return(temp);
436 }
437 
438 /*BFUNC
439 
440 enter() is used to enter a Reserved Word or ID into the hash table.
441 
442 EFUNC*/
443 
444 static struct id *enter(tokentype,str,len)
445      int tokentype;
446      char *str;
447      int len;
448 {
449   BEGIN("enter")
450   int hashnum;
451   LINK *temp,*current;
452   char *ptr;
453 
454   for(ptr=str;*ptr!='\0';ptr++)          /* All capitals is fine */
455     {
456       if ((*ptr>='a') && (*ptr<='z'))
457   {
458     *ptr = *ptr - ('a'-'A');
459   }
460     }
461   hashnum = hashpjw(str);                /* Check if in hash table */
462   for(temp=NULL,current=HashTable[hashnum];
463       current!= NULL;
464       current=current->next)
465     {
466       if (strcmp(str,current->lid->name) == 0)
467   {
468     temp=current;
469     break;
470   }
471     }
472   if (temp)                          /* Yes, found ID then return */
473     {
474       temp->lid->count++;
475       return(temp->lid);
476     }
477   else                              /* Else make our own ID and return that*/
478     {
479       temp = MakeLink(tokentype,str,len);
480       InsertLink(temp,HashTable[hashnum]);
481       return(temp->lid);
482     }
483 }
484 
485 /*BFUNC
486 
487 getint() takes an integer from the input.
488 
489 EFUNC*/
490 
491 static int getint()
492 {
493   BEGIN("getint")
494   int type;
495   if ((type=yylex())!=R_INTEGER)
496     {
497       printf("Bad input, not integer, '%s' on line %d\n",
498        yytext,
499        yylineno);
500       return(0);
501     }
502   return(yyint);
503 }
504 
505 /*BFUNC
506 
507 getstr() gets a string from the input. It copies the string to
508 temporary storage before it returns the pointer.
509 
510 EFUNC*/
511 
512 static char *getstr()
513 {
514   BEGIN("getstr")
515   char *tmp,*ptr,*bptr;
516   int i,accum,flag;
517   if (yylex() != R_STRING)                      /* Check if string */
518     {
519       printf("String expected.\n");
520       if (!(tmp=(char *) malloc(sizeof(char))))
521   {
522     WHEREAMI();
523     printf("Cannot allocate for null string.\n");
524     exit(ERROR_MEMORY);
525   }
526       *tmp='\0';
527       return(tmp);
528     }
529   if (!(tmp=(char *)calloc(strlen(yytext)+1,sizeof(char)))) /* Make space */
530     {
531       WHEREAMI();
532       printf("Cannot allocate %d string space.\n",yyleng);
533       exit(ERROR_MEMORY);
534     }
535   for(bptr=yytext+1,ptr=tmp;*bptr!='"';bptr++,ptr++)   /* Copy to string */
536     {
537       if (*bptr=='\\')
538   {
539     bptr++;
540     for(flag=0,accum=0,i=0;i<3;i++)  /* Octal character lookahead */
541       {
542         if ((*bptr>='0')&&(*bptr<='7'))
543     {
544       accum = (accum<<3)+(*bptr-'0');
545       bptr++;
546       flag=1;
547     }
548         else
549     {
550       break;
551     }
552       }
553     if (flag)
554       {
555         bptr--;
556         *ptr=accum;
557       }
558     else                           /* Do conversions, if necessary */
559       {
560         switch(*(bptr))
561     {
562     case '0':
563       *ptr = 0;
564       break;
565     case 'b':
566       *ptr = 0x8;
567       break;
568     case 'i':
569       *ptr = 0x9;
570       break;
571     case 'n':
572       *ptr = 0xa;
573       break;
574     case 'v':
575       *ptr = 0xb;
576       break;
577     case 'f':
578       *ptr = 0xc;
579       break;
580     case 'r':
581       *ptr = 0xd;
582       break;
583     default:
584       *ptr=(*bptr);
585     }
586       }
587   }
588       else
589   {
590     *ptr = (*bptr);
591   }
592     }
593   *ptr='\0';
594   return(tmp);
595 }
596 
597 /*BFUNC
598 
599 parser() handles all of the parsing required for the Command
600 Interpreter.  It is basically a while statement with a very large case
601 statement for every input. The Command Interpreter is essentially
602 driven by the keywords. All unmatched values such as integers,
603 strings, and brackets, are ignored.
604 
605 EFUNC*/
606 
607 #define ARRAYBEGIN if (ntoken==R_LBRACKET)\
608       {\
609         arrayflag=1;\
610         ntoken=yylex();\
611       }\
612     if (ntoken!=R_INTEGER)\
613       {\
614         WHEREAMI();\
615         printf("Expected integer.\n");\
616         break;\
617       }\
618     while(1)\
619       {
620 
621 #define ARRAYEND  if (arrayflag)\
622     {\
623       if ((ntoken=yylex())==R_RBRACKET) break;\
624       else if (ntoken!=R_INTEGER)\
625         {\
626           WHEREAMI();\
627           printf("Expected integer or right bracket.\n");\
628           break;\
629         }\
630     }\
631         else break;\
632         }
633 
634 void parser()
635 {
636   BEGIN("parser")
637   int i,dest,value,token,ntoken,arrayflag;
638   int accum;
639   int Start,End;
640   int *ptr,*ptr2;
641 
642   while((token=yylex()))        /* The code handling is simple enough. */
643     {                         /* just read the code and documentation */
644       ErrorValue=0;           /* book... */
645       arrayflag=0;
646       switch(token)
647   {
648   case R_ECHO:
649     printf("%s\n",getstr());
650     break;
651   case R_PRINTIMAGE:
652     PrintImage();
653     break;
654   case R_PRINTFRAME:
655     PrintFrame();
656     break;
657   case R_PRINTSCAN:
658     PrintScan();
659     break;
660   case R_COMPONENT:
661     ntoken=yylex();
662     ARRAYBEGIN;
663     dest = yyint;
664     InBounds(dest,0,MAXIMUM_COMPONENTS-1,"Bad component reference");
665     if (ErrorValue) break;
666     if (yylex()!=R_LBRACKET)
667       {
668         WHEREAMI();
669         printf("Expected left bracket.\n");
670         break;
671       }
672     CFrame->ComponentFileName[dest] = getstr();
673     value=getint();
674     InBounds(value,0,MAXIMUM_HORIZONTAL_FREQUENCY,
675        "Bad horizontal frequency");
676     if (ErrorValue) break;
677     CFrame->hf[dest]=value;
678     value=getint();
679     InBounds(value,0,MAXIMUM_VERTICAL_FREQUENCY,
680        "Bad vertical frequency");
681     if (ErrorValue) break;
682     CFrame->vf[dest]=value;
683     value=getint();
684     InBounds(value,0,MAXIMUM_DEVICES-1,"Bad device reference");
685     if (ErrorValue) break;
686     CFrame->tq[dest]=value;
687     CFrame->cn[CFrame->GlobalNumberComponents++]=dest;/*Know to use it*/
688     if (yylex()!=R_RBRACKET)
689       {
690         WHEREAMI();
691         printf("Expected right bracket.\n");
692         break;
693       }
694     ARRAYEND;
695     break;
696   case R_SCAN:
697     CScan->NumberComponents=0;
698     ntoken=yylex();
699     ARRAYBEGIN;
700     if (CScan->NumberComponents>=MAXIMUM_SOURCES)
701       {
702         WHEREAMI();
703         printf("Exceeded number of sources per scan.\n");
704         break;
705       }
706     InBounds(yyint,0,MAXIMUM_COMPONENTS-1,"Bad component reference");
707     if (ErrorValue) break;
708     for(i=0;i<CFrame->GlobalNumberComponents;i++)  /* Check there */
709             if (CFrame->cn[i]==yyint) break;
710     if (i==CFrame->GlobalNumberComponents)
711       {
712         WHEREAMI();
713         printf("Scan index not defined in frame yet.\n");
714         break;
715       }
716     CScan->ci[CScan->NumberComponents] = yyint;
717     if (yylex()!=R_LBRACKET)
718       {
719         WHEREAMI();
720         printf("Expected left bracket.\n");
721         break;
722       }
723     value=getint();
724     InBounds(value,0,MAXIMUM_DEVICES-1,"Bad device reference");
725     if (ErrorValue) break;
726     CScan->td[CScan->NumberComponents]=value;
727     value=getint();
728     InBounds(value,0,MAXIMUM_DEVICES-1,"Bad device reference");
729     if (ErrorValue) break;
730     CScan->ta[CScan->NumberComponents]=value;
731     CScan->NumberComponents++;
732     if (yylex()!=R_RBRACKET)
733       {
734         WHEREAMI();
735         printf("Expected right bracket.\n");
736         break;
737       }
738     ARRAYEND;
739     break;
740   case R_QUANTIZATION:
741     ntoken=yylex();
742     ARRAYBEGIN;
743     dest = yyint;
744     InBounds(dest,0,MAXIMUM_DEVICES-1,
745        "Bad quantization reference.");
746     if (ErrorValue) break;
747     ntoken=yylex();
748     if (ntoken==R_LUMINANCEDEFAULT)
749       {
750         CImage->QuantizationMatrices[dest]=LuminanceQuantization;
751         break;
752       }
753     else if (ntoken==R_CHROMINANCEDEFAULT)
754       {
755         CImage->QuantizationMatrices[dest]=ChrominanceQuantization;
756         break;
757       }
758     else if (ntoken!=R_LBRACKET)
759       {
760         WHEREAMI();
761         printf("Expected left bracket.\n");
762         break;
763       }
764     CImage->NumberQuantizationMatrices =
765       MAX(CImage->NumberQuantizationMatrices,(dest+1));
766     if (!(ptr=(int *)calloc(64,sizeof(int))))
767       {
768         WHEREAMI();
769         printf("Cannot allocate quantization matrix.\n");
770         exit(ERROR_MEMORY);
771       }
772     CImage->NumberQuantizationMatrices =
773       MAX(CImage->NumberQuantizationMatrices,(dest+1));
774     CImage->QuantizationMatrices[dest]=ptr;
775     for(i=0;i<64;i++)
776       {
777         ptr[i]=16;
778       }
779     for(i=0;i<65;i++,ptr++) /* One additional to force r-bracket */
780       {
781         if ((ntoken=yylex())!=R_INTEGER) break;
782         InBounds(yyint,1,65535,"Integer out of bounds");
783         if (ErrorValue) yyint=16;
784         *ptr = yyint;
785       }
786     if (ntoken!=R_RBRACKET)
787       {
788         WHEREAMI();
789         printf("Expected integer or right bracket.\n");
790         break;
791       }
792     ARRAYEND;
793     break;
794   case R_ACSEND:
795     ntoken=yylex();
796     if (ntoken==R_EMPTY)
797       {
798         CScan->NumberACTablesSend = 0;
799         break;
800       }
801     ARRAYBEGIN;
802     if (CScan->NumberACTablesSend>=MAXIMUM_DEVICES)
803       {
804         WHEREAMI();
805         printf("AC Huffman queue full.\n");
806         break;
807       }
808     InBounds(yyint,0,MAXIMUM_DEVICES-1,"Bad device reference");
809     if (ErrorValue) break;
810     CScan->sa[CScan->NumberACTablesSend++] = yyint;
811     ARRAYEND;
812     break;
813   case R_DCSEND:
814     ntoken=yylex();
815     if (ntoken==R_EMPTY)
816       {
817         CScan->NumberDCTablesSend = 0;
818         break;
819       }
820     ARRAYBEGIN;
821     if (CScan->NumberDCTablesSend>=MAXIMUM_DEVICES)
822       {
823         WHEREAMI();
824         printf("DC Huffman queue full.\n");
825         break;
826       }
827     InBounds(yyint,0,MAXIMUM_DEVICES-1,"Bad device reference");
828     if (ErrorValue) break;
829     CScan->sd[CScan->NumberDCTablesSend++] = yyint;
830     ARRAYEND;
831     break;
832   case R_QSEND:
833     ntoken=yylex();
834     if (ntoken==R_EMPTY)
835       {
836         CScan->NumberQTablesSend = 0;
837         break;
838       }
839     ARRAYBEGIN;
840     if (CScan->NumberQTablesSend>=MAXIMUM_DEVICES)
841       {
842         WHEREAMI();
843         printf("Quantization queue full.\n");
844         break;
845       }
846     InBounds(yyint,0,MAXIMUM_DEVICES-1,"Bad device reference");
847     if (ErrorValue) break;
848     CScan->sq[CScan->NumberQTablesSend++] = yyint;
849     ARRAYEND;
850     break;
851   case R_STREAMNAME:
852     CImage->StreamFileName = getstr();
853     break;
854   case R_IMAGEWIDTH:
855     value=getint();
856     InBounds(value,0,MAXIMUM_IMAGE_WIDTH,"Bad image width");
857     CFrame->GlobalWidth = value;
858     break;
859   case R_IMAGEHEIGHT:
860     value=getint();
861     InBounds(value,0,MAXIMUM_IMAGE_HEIGHT,"Bad image height");
862     CFrame->GlobalHeight = value;
863     break;
864   case R_SCANDNL:
865     ntoken=yylex();
866     switch(ntoken)
867       {
868       case R_AUTO:
869         CFrame->InsertDnl= -2;
870         break;
871       case R_ENABLE:
872         CFrame->InsertDnl= -1;
873         break;
874       case R_INTEGER:
875         CFrame->InsertDnl = yyint;
876         break;
877       default:
878         WHEREAMI();
879         printf("Expected integer.\n");
880         break;
881       }
882     break;
883   case R_FRAMEWIDTH:
884     ntoken=yylex();
885     ARRAYBEGIN;
886     dest = yyint;
887     InBounds(dest,0,MAXIMUM_COMPONENTS-1,"Bad component destination");
888     if (ErrorValue) break;
889     value=getint();
890     InBounds(value,0,MAXIMUM_IMAGE_WIDTH,"Bad frame width");
891     if (ErrorValue) break;
892     CFrame->Width[dest] = value;
893     ARRAYEND;
894     break;
895   case R_FRAMEHEIGHT:
896     ntoken=yylex();
897     ARRAYBEGIN;
898     dest = yyint;
899     InBounds(dest,0,MAXIMUM_COMPONENTS-1,"Bad component destination");
900     if (ErrorValue) break;
901     value=getint();
902     InBounds(value,0,MAXIMUM_IMAGE_HEIGHT,"Bad frame height");
903     if (ErrorValue) break;
904     CFrame->Height[dest] = value;
905     ARRAYEND;
906     break;
907   case R_RESYNC:
908     value = getint();
909     InBounds(value,0,MAXIMUM_RESYNC_INTERVAL,"Bad resync interval");
910     if (ErrorValue) break;
911     CFrame->ResyncInterval = value;
912     break;
913   case R_BUFFER:
914     value = getint();
915     InBounds(value,MINIMUM_BUFFERSIZE,
916        MAXIMUM_BUFFERSIZE,"Bad buffersize");
917     if (ErrorValue) break;
918     CFrame->BufferSize = value;
919     break;
920   case R_OPENSCAN:
921     CheckValidity();
922     CheckBaseline();
923     ConfirmFileSize();
924     MakeIob(IOB_BLOCK,O_RDONLY,1);
925     break;
926   case R_CLOSESCAN:
927     for(i=0;i<CScan->NumberComponents;i++)  /* Close all components */
928       {
929         InstallIob(i);
930         CloseIob();
931       }
932     break;
933   case R_OPENSTREAM:
934     if (CImage->StreamFileName)
935       {
936         swopen(CImage->StreamFileName,0);  /* Index 0 open */
937       }
938     else
939       {
940         printf("StreamFileName: Null. Failed\n");
941       }
942     break;
943   case R_CLOSESTREAM:
944     swclose();
945     break;
946   case R_FREQUENCY:
947     JpegFrequencyScan();
948     break;
949   case R_WRITESPECIAL:
950     ntoken=yylex();
951     ARRAYBEGIN;
952     value = yyint;
953     swbytealign();
954     bputc(0xFF);  /* Marker */
955     bputc(value&0xff);
956     Start = swtell();
957     bputw(0);
958     if (yylex()!=R_LBRACKET)
959       {
960         WHEREAMI();
961         printf("Expected left bracket.\n");
962         End = swtell();
963         swseek(Start);
964         bputw((End-Start) >> 3);
965         swseek(End);
966         break;
967       }
968     while((ntoken=yylex())==R_INTEGER)
969       {
970         bputc(yyint&0xff);
971       }
972     if (ntoken!=R_RBRACKET)
973       {
974         WHEREAMI();
975         printf("Expected integer or right bracket.\n");
976         End = swtell();
977         swseek(Start);
978         bputw((End-Start) >> 3);
979         swseek(End);
980         break;
981       }
982     End = swtell();
983     swseek(Start);
984     bputw((End-Start) >> 3);
985     swseek(End);
986     ARRAYEND;
987     break;
988   case R_WRITEDIRECT:
989     swbytealign();
990     if (yylex()!=R_LBRACKET)
991       {
992         WHEREAMI();
993         printf("Expected left bracket.\n");
994         break;
995       }
996     while((ntoken=yylex())==R_INTEGER)
997       {
998         bputc(yyint&0xff);
999       }
1000     if (ntoken!=R_RBRACKET)
1001       {
1002         WHEREAMI();
1003         printf("Expected integer or right bracket.\n");
1004         break;
1005       }
1006     break;
1007   case R_WRITESCAN:
1008     JpegEncodeScan();
1009     break;
1010   case R_WRITEFRAME:
1011     MakeConsistentFrameSize();  /* Do it here when everything defined */
1012     WriteSof();
1013     break;
1014   case R_WRITESOI:
1015     WriteSoi();
1016     break;
1017   case R_WRITEEOI:
1018     WriteEoi();
1019     break;
1020   case R_WRITEQUANTIZATION:
1021     WriteDqt();
1022     break;
1023   case R_WRITERESYNC:
1024     WriteDri();
1025     break;
1026   case R_WRITEDNL:
1027     WriteDnl();
1028     break;
1029   case R_WRITEHUFFMAN:
1030     WriteDht();
1031     break;
1032   case R_ACCUSTOM:
1033     ntoken=yylex();
1034     ARRAYBEGIN;
1035     dest = yyint;
1036     InBounds(dest,0,MAXIMUM_DEVICES-1,"Bad device reference");
1037     if (ErrorValue) break;
1038     if (yylex()!=R_LBRACKET)
1039       {
1040         WHEREAMI();
1041         printf("Expected left bracket.\n");
1042         break;
1043       }
1044     MakeXhuff();
1045     MakeEhuff();
1046     if (!(ptr=(int *)calloc(257,sizeof(int))))
1047       {
1048         WHEREAMI();
1049         printf("Out of custom frequency space.\n");
1050         exit(ERROR_MEMORY);
1051       }
1052     for(i=0;i<257;i++)
1053       {
1054         ptr[i]=0;
1055       }
1056     while((ntoken=yylex())==R_INTEGER)
1057       {
1058         InBounds(yyint,0,MAXIMUM_SOURCES-1,"Bad frequency reference");
1059         if(ErrorValue) yyint=0;
1060         AddFrequency(ptr,CScan->ACFrequency[yyint]);
1061       }
1062     if (ntoken!=R_RBRACKET)
1063       {
1064         WHEREAMI();
1065         printf("Expected right bracket.\n");
1066         break;
1067       }
1068     MakeHuffman(ptr);
1069     SetACHuffman(dest);
1070     CImage->NumberACTables =
1071       MAX(CImage->NumberACTables,(dest+1));
1072     ARRAYEND;
1073     break;
1074   case R_DCCUSTOM:
1075     ntoken=yylex();
1076     ARRAYBEGIN;
1077     dest = yyint;
1078     InBounds(dest,0,MAXIMUM_DEVICES-1,"Bad device reference");
1079     if (ErrorValue) break;
1080     if (yylex()!=R_LBRACKET)
1081       {
1082         WHEREAMI();
1083         printf("Expected left bracket.\n");
1084         break;
1085       }
1086     MakeXhuff();
1087     MakeEhuff();
1088     if (!(ptr=(int *)calloc(257,sizeof(int))))
1089       {
1090         WHEREAMI();
1091         printf("Out of custom frequency space.\n");
1092         exit(ERROR_MEMORY);
1093       }
1094     for(i=0;i<257;i++)
1095       {
1096         ptr[i]=0;
1097       }
1098     while((ntoken=yylex())==R_INTEGER)
1099       {
1100         InBounds(yyint,0,MAXIMUM_SOURCES-1,"Bad frequency reference");
1101         if(ErrorValue) yyint=0;
1102         AddFrequency(ptr,CScan->DCFrequency[yyint]);
1103       }
1104     if (ntoken!=R_RBRACKET)
1105       {
1106         WHEREAMI();
1107         printf("Expected right bracket.\n");
1108         break;
1109       }
1110     MakeHuffman(ptr);
1111     SetDCHuffman(dest);
1112     CImage->NumberDCTables =
1113       MAX(CImage->NumberDCTables,(dest+1));
1114     ARRAYEND;
1115     break;
1116   case R_ACSPEC:
1117     ntoken=yylex();
1118     ARRAYBEGIN;
1119     dest = yyint;
1120     InBounds(dest,0,MAXIMUM_DEVICES-1,"Bad device reference");
1121     if (ErrorValue) break;
1122     MakeXhuff();
1123     MakeEhuff();
1124     if ((ntoken=yylex())==R_LBRACKET)
1125       {
1126         if (!(ptr=(int *)calloc(38,sizeof(int)))) /* Get bits */
1127     {
1128       WHEREAMI();
1129       printf("Out of custom bits space.\n");
1130       exit(ERROR_MEMORY);
1131     }
1132         for(i=0;i<32;i++)
1133     {
1134       ptr[i]=0;
1135     }
1136         for(accum=0,i=0;i<17;i++) /* First index is bitlength of 1. */
1137     {                 /* One additional to force r-bracket. */
1138       ntoken=yylex();
1139       if (ntoken==R_INTEGER)
1140         {
1141           accum+=yyint;
1142           ptr[i]=yyint;
1143         }
1144       else break;
1145     }
1146         if (ntoken!=R_RBRACKET)
1147     {
1148       WHEREAMI();
1149       printf("Expected integer or right bracket.\n");
1150       break;
1151     }
1152         if (yylex()!=R_LBRACKET)  /* Get values */
1153     {
1154       WHEREAMI();
1155       printf("Expected left bracket.\n");
1156       break;
1157     }
1158         if (!(ptr2=(int *)calloc(257,sizeof(int))))
1159     {
1160       WHEREAMI();
1161       printf("Out of custom Huffman value space.\n");
1162       exit(ERROR_MEMORY);
1163     }
1164         for(i=0;i<257;i++)
1165     {
1166       ptr2[i]=0;
1167     }
1168         for(i=0;i<257;i++) /* One additinal to force r-bracket */
1169     {
1170       ntoken=yylex();
1171       if (ntoken==R_INTEGER)
1172         {
1173           ptr2[i]=yyint;
1174         }
1175       else break;
1176     }
1177         if (i!=accum)
1178     {
1179       WHEREAMI();
1180       printf("Number of bitlengths != number of values.");
1181     }
1182         if (ntoken!=R_RBRACKET)
1183     {
1184       WHEREAMI();
1185       printf("Expected integer or right bracket.\n");
1186       break;
1187     }
1188         SpecifiedHuffman(ptr,ptr2);
1189       }
1190     else if (ntoken==R_CHROMINANCEDEFAULT)
1191       {
1192         SpecifiedHuffman(ChrominanceACBits,ChrominanceACValues);
1193       }
1194     else if (ntoken==R_LUMINANCEDEFAULT)
1195       {
1196         SpecifiedHuffman(LuminanceACBits,LuminanceACValues);
1197       }
1198     else
1199       {
1200         WHEREAMI();
1201         printf("Expected left bracket or ACDEFAULT.\n");
1202         break;
1203       }
1204     SetACHuffman(dest);
1205     CImage->NumberACTables =
1206       MAX(CImage->NumberACTables,(dest+1));
1207     ARRAYEND;
1208     break;
1209   case R_DCSPEC:
1210     ntoken=yylex();
1211     ARRAYBEGIN;
1212     dest = yyint;
1213     InBounds(dest,0,MAXIMUM_DEVICES-1,"Bad device reference");
1214     if (ErrorValue) break;
1215     MakeXhuff();
1216     MakeEhuff();
1217     if ((ntoken=yylex())==R_LBRACKET)
1218       {
1219         if (!(ptr=(int *)calloc(38,sizeof(int)))) /* Get bits */
1220     {
1221       WHEREAMI();
1222       printf("Out of custom bits space.\n");
1223       exit(ERROR_MEMORY);
1224     }
1225         for(i=0;i<32;i++)
1226     {
1227       ptr[i]=0;
1228     }
1229         for(accum=0,i=0;i<17;i++) /* First index is bitlength of 1. */
1230     {                /* 0-16 to force right bracket. */
1231       ntoken=yylex();
1232       if (ntoken==R_INTEGER)
1233         {
1234           accum+=yyint;
1235           ptr[i]=yyint;
1236         }
1237       else break;
1238     }
1239         if (ntoken!=R_RBRACKET)
1240     {
1241       WHEREAMI();
1242       printf("Expected integer or right bracket.\n");
1243       break;
1244     }
1245         if (yylex()!=R_LBRACKET)  /* Get values */
1246     {
1247       WHEREAMI();
1248       printf("Expected left bracket.\n");
1249       break;
1250     }
1251         if (!(ptr2=(int *)calloc(257,sizeof(int))))
1252     {
1253       WHEREAMI();
1254       printf("Out of custom Huffman value space.\n");
1255       exit(ERROR_MEMORY);
1256     }
1257         for(i=0;i<257;i++)
1258     {
1259       ptr2[i]=0;
1260     }
1261         for(i=0;i<257;i++) /*One additional to force r-bracket.*/
1262     {
1263       ntoken=yylex();
1264       if (ntoken==R_INTEGER)
1265         {
1266           ptr2[i]=yyint;
1267         }
1268       else break;
1269     }
1270         if (i!=accum)
1271     {
1272       WHEREAMI();
1273       printf("Number of bitlengths != number of values.");
1274     }
1275         if (ntoken!=R_RBRACKET)
1276     {
1277       WHEREAMI();
1278       printf("Expected integer or right bracket.\n");
1279       break;
1280     }
1281         SpecifiedHuffman(ptr,ptr2);
1282       }
1283     else if (ntoken==R_CHROMINANCEDEFAULT)
1284       {
1285         SpecifiedHuffman(ChrominanceDCBits,ChrominanceDCValues);
1286       }
1287     else if (ntoken==R_LUMINANCEDEFAULT)
1288       {
1289         SpecifiedHuffman(LuminanceDCBits,LuminanceDCValues);
1290       }
1291     else
1292       {
1293         WHEREAMI();
1294         printf("Expected left bracket or DCDEFAULT.\n");
1295         break;
1296       }
1297     SetDCHuffman(dest);
1298     CImage->NumberDCTables =
1299       MAX(CImage->NumberDCTables,(dest+1));
1300     ARRAYEND;
1301     break;
1302   }
1303     }
1304 }
1305 
1306 /*NOPROTO*/
1307 /*END*/
1308