KSquare Utilities
ScannerFile4BitEncoded.cpp
Go to the documentation of this file.
1 #include "FirstIncludes.h"
2 #include <stdio.h>
3 #include <errno.h>
4 #include <string.h>
5 #include <ctype.h>
6 #include <iostream>
7 #include <fstream>
8 #include <map>
9 #include <vector>
10 #include "MemoryDebug.h"
11 using namespace std;
12 
13 #include "GlobalGoalKeeper.h"
14 #include "KKBaseTypes.h"
15 #include "OSservices.h"
16 #include "RunLog.h"
17 #include "KKStr.h"
18 using namespace KKB;
19 
20 
21 #include "ScannerFile.h"
22 
23 #include "Variables.h"
24 
26 
27 using namespace KKLSC;
28 
29 #pragma pack(push,1)
31 {
32  uchar opCode: 4; /** 0 = End of Scan Line. */
34 };
35 
36 
37 
39 {
40  /** Will handle text blocks in one or more sections with 2^11 characters in each *
41  * The last section will have 'endOfText' == '1' */
42 
43  uchar opCode: 4; /**< 1 = Text Block. */
44  uchar endOfText: 1; /**< 0 = More Text blocks to follow, 1 = last text block. */
45  uchar lenHighBits: 3; /**< Len = 16 * lenHighBits + lenLowBits */
46 }; /* OpRecTextBlock1 */
47 
48 
49 
51 {
52  uchar lenLowBits: 8; /**< Add this value to the prev rec 'lenHighBits' field to get the length of the text block. */
53 };
54 
55 
56 
58 {
59  uchar opCode: 4; /**< 2 = InstrumentDataWord 32 Bit Instrument Data */
61 };
62 
63 
64 
66 {
69 }; /**< OpCode 2 */
70 
71 
72 
74 {
77 }; /**< OpCode 2 */
78 
79 
80 
81 
83 {
84  /** For one or two raw pixels */
85  uchar opCode :4; /**< 4 = 2 Pixels
86  * 5 = 3 Pixels
87  * 6 = 4 Pixels
88  * 7 = 5 Pixels
89  * 8 = 6 Pixels
90  * 9 = 7 Pixels
91  */
93 }; /* OpRecRunLen */
94 
95 
96 
98 {
99  /** For one or two raw pixels */
100  uchar opCode :4; /**< 10 = up to 256 run-length */
102 }; /* OpRecRunLen */
103 
104 
105 
107 {
108  uchar runLen :8; /**< 0= 1-Pixel, 1=2-Pixels, ... 255=256-Pixels */
109 }; /* OpRecRunLen */
110 
111 
112 
114 {
115  uchar opCode :4; /**< 11 = One raw pixel */
117 }; /* OpRecRaw1Pixel */
118 
119 
120 
122 {
123  uchar opCode :4; /**< 12 = Even run length 2 thru 32 pixels */
124  uchar len :4; /**< Num-Raw-Pixels = (len + 1) * 2 */
125  /** To be followed by 'len' RawPixel recs */
126 }; /* OpRecRunLen1Bit */
127 
128 
129 
131 {
132  uchar opCode :4; /**< 13 = Odd number of pixels, up to 513 pixels. */
133  uchar lenHigh :4; /**< Num-Raw-Pixels = 1 + 2 * (1 + lenHigh * 16 + lenLow) */
134  /** To be followed by length RawPixelRec's */
135 }; /* OpRecRaw513Pixels1 */
136 
137 
138 
140 {
141  uchar lenLow :4; /**< 13 = Odd number of pixes, up to 513 pixels. */
142  uchar pix0 :4; /**< 1st Raw pixel */
143 
144  /** To be followed by (1 + lenHigh * 16 + lenLow) 'RawPixelRecs' */
145 }; /* OpRecRaw513Pixels2 */
146 
147 
148 
150 {
153 }; /* OpRecord */
154 
155 
156 
158 {
160 
161  OpRecTextBlock1 textBlock1; /**< OpCode 1 */
163 
165  OpRecRunLen runLen; /**< OpCodes 4 thru 9 */
166 
167  OpRecRun256Len1 run256Len1; /**< OpCode 10 */
169 
170  OpRecRaw1Pixel raw1Pixel; /**< OpCode 11 */
171 
172  OpRecRaw32Pixels raw32Pixels; /**< OpCode 12 */
173 
176 
177  RawPixelRec rawPixels; /* Two 4 bit pixels */
178 
180 }; /* OpRec */
181 
182 
183 
184 #pragma pack(pop)
185 
186 
187 uchar* ScannerFile4BitEncoded::convTable4BitTo8Bit = NULL;
188 uchar* ScannerFile4BitEncoded::convTable8BitTo4Bit = NULL;
189 uchar* ScannerFile4BitEncoded::compensationTable = NULL;
190 
191 
193  RunLog& _log
194  ):
195  ScannerFile (_fileName, _log),
196  rawPixelRecBuffer (NULL),
197  rawPixelRecBufferSize (0),
198  rawPixelRecBufferLen (0),
199 
200  encodedBuff (NULL),
201  encodedBuffLen (0),
202  encodedBuffNext (NULL),
203  encodedBuffSize (0),
204 
205  rawStr (NULL),
206  rawStrLen (0),
207  rawStrSize (0),
208  runLen (0),
209  runLenChar (0),
210  curCompStatus (csNull)
211 
212 {
213  BuildConversionTables ();
214  PrintSizeInfo ();
215 }
216 
217 
218 
220  kkuint32 _pixelsPerScanLine,
221  kkuint32 _frameHeight,
222  RunLog& _log
223  ):
224  ScannerFile (_fileName, _pixelsPerScanLine, _frameHeight, _log),
225  rawPixelRecBuffer (NULL),
226  rawPixelRecBufferSize (0),
227  rawPixelRecBufferLen (0),
228  encodedBuff (NULL),
229  encodedBuffLen (0),
230  encodedBuffNext (NULL),
231  encodedBuffSize (0),
232  rawStr (NULL),
233  rawStrLen (0),
234  rawStrSize (0),
235  runLen (0),
236  runLenChar (0),
237  curCompStatus (csNull)
238 {
239  BuildConversionTables ();
240  AllocateEncodedBuff ();
241  AllocateRawStr (_pixelsPerScanLine + 100);
242 }
243 
244 
245 
246 void ScannerFile4BitEncoded::PrintSizeInfo ()
247 {
248  /*
249  #pragma pack(1)
250  int x01 = sizeof (OpRecEndOfScanLine ) ;
251  int x02 = sizeof (OpRecTextBlock1 ) ;
252  int x03 = sizeof (OpRecTextBlock2 ) ;
253  int x04 = sizeof (OpRecRunLen ) ;
254  int x05 = sizeof (OpRecRun256Len1 ) ;
255  int x06 = sizeof (OpRecRun256Len2 ) ;
256  int x07 = sizeof (OpRecRaw1Pixel ) ;
257  int x08 = sizeof (OpRecRaw32Pixels ) ;
258  int x09 = sizeof (OpRecRaw513Pixels1 ) ;
259  int x10 = sizeof (OpRecRaw513Pixels2 ) ;
260  int x11 = sizeof (RawPixelRec ) ;
261  int x12 = sizeof (OpRec );
262 
263 
264  cout << endl
265  << "OpRecEndOfScanLine " << "\t" << sizeof (OpRecEndOfScanLine ) << endl
266  << "OpRecTextBlock1 " << "\t" << sizeof (OpRecTextBlock1 ) << endl
267  << "OpRecTextBlock2 " << "\t" << sizeof (OpRecTextBlock2 ) << endl
268  << "OpRecRunLen " << "\t" << sizeof (OpRecRunLen ) << endl
269  << "OpRecRun256Len1 " << "\t" << sizeof (OpRecRun256Len1 ) << endl
270  << "OpRecRun256Len2 " << "\t" << sizeof (OpRecRun256Len2 ) << endl
271  << "OpRecRaw1Pixel " << "\t" << sizeof (OpRecRaw1Pixel ) << endl
272  << "OpRecRaw32Pixels " << "\t" << sizeof (OpRecRaw32Pixels ) << endl
273  << "OpRecRaw513Pixels1 " << "\t" << sizeof (OpRecRaw513Pixels1 ) << endl
274  << "OpRecRaw513Pixels2 " << "\t" << sizeof (OpRecRaw513Pixels2 ) << endl
275  << "RawPixelRec " << "\t" << sizeof (RawPixelRec ) << endl
276  << endl;
277  */
278 }
279 
280 
281 
283 {
284  if (opened)
285  Close ();
286 
287  delete encodedBuff; encodedBuff = NULL;
288  delete rawPixelRecBuffer; rawPixelRecBuffer = NULL;
289  delete rawStr; rawStr = NULL;
290 }
291 
292 
293 
294 
295 void ScannerFile4BitEncoded::AllocateRawPixelRecBuffer (kkuint32 size)
296 {
297  delete rawPixelRecBuffer;
298  rawPixelRecBuffer = new RawPixelRec[size];
299  rawPixelRecBufferSize = size;
300  rawPixelRecBufferLen = 0;
301 } /* AllocateRawPixelRecBuffer */
302 
303 
304 
305 void ScannerFile4BitEncoded::AllocateRawStr (kkuint16 size)
306 {
307  if (rawStr)
308  {
309  uchar* newRawStr = new uchar[size];
310  kkuint16 bytesToCopy = Min (rawStrLen, size);
311  memcpy (newRawStr, rawStr, bytesToCopy);
312  delete rawStr;
313  rawStr = NULL;
314  rawStrLen = bytesToCopy;
315  rawStrSize = size;
316  }
317  else
318  {
319  rawStrSize = size;
320  rawStrLen = 0;
321  rawStr = new uchar[rawStrSize];
322  }
323 } /* AllocateRawStr */
324 
325 
326 
327 
328 void ScannerFile4BitEncoded::AllocateEncodedBuff ()
329 {
330  delete encodedBuff; encodedBuff = NULL;
331 
332  kkint32 frameWidth = Max ((kkuint32)2048, 4 * PixelsPerScanLine ());
333 
334  encodedBuffSize = (int)(1.2f * (float)frameWidth);
335 
336  encodedBuff = new OpRec[encodedBuffSize];
337  encodedBuffNext = encodedBuff;
338  //encodedBuffSize = encodedBuffSize;
339  encodedBuffLen = 0;
340 } /* AllocateEncodedBuff */
341 
342 
343 
344 void ScannerFile4BitEncoded::ReSizeEncodedBuff (kkuint32 newSize)
345 {
346  OpRecPtr newEncodedBuff = new OpRec[newSize];
347 
348  kkuint32 recsToMove = Min (newSize, encodedBuffLen);
349 
350  memcpy (newEncodedBuff, encodedBuff, recsToMove * sizeof (OpRec));
351  encodedBuffNext = newEncodedBuff + (encodedBuffNext - encodedBuff);
352 
353  delete encodedBuff;
354  encodedBuff = newEncodedBuff;
355  encodedBuffSize = newSize;
356 } /* ReSizeEncodedBuff */
357 
358 
359 
360 void ScannerFile4BitEncoded::BuildConversionTables ()
361 {
363  if (!convTable4BitTo8Bit)
364  {
365  kkint32 x = 0;
366  kkint32 y = 0;
367  kkint32 inc = 256 / 16;
368  convTable4BitTo8Bit = new uchar[16];
369  convTable8BitTo4Bit = new uchar[256];
370  for (x = 0; x < 16; ++x)
371  {
372  kkint32 this8Bit = x * inc;
373  kkint32 next8Bit = (x + 1) * inc;
374 
375  kkint32 fourBitTo8BitNum = (kkint32)(this8Bit + (kkint32)(((float)x / 16.0f) * (float)inc));
376 
377  convTable4BitTo8Bit[x] = (uchar)fourBitTo8BitNum;
378  for (y = this8Bit; y < next8Bit; ++y)
379  convTable8BitTo4Bit[y] = x;
380  }
381 
382  compensationTable = new uchar[256];
383  for (kkint16 pv = 0; pv < 256; ++pv)
384  {
385  uchar encodedValue = convTable8BitTo4Bit[pv];
386  compensationTable[pv] = convTable4BitTo8Bit[encodedValue];
387  }
388  atexit (ScannerFile4BitEncoded::ExitCleanUp);
389  }
390 
392 } /* BuildConversionTables */
393 
394 
395 
397 {
399  if (!compensationTable)
400  BuildConversionTables ();
402  return compensationTable;
403 } /* CompensationTable */
404 
405 
406 
407 
408 
409 void ScannerFile4BitEncoded::ExitCleanUp ()
410 {
412  delete convTable4BitTo8Bit; convTable4BitTo8Bit = NULL;
413  delete convTable8BitTo4Bit; convTable8BitTo4Bit = NULL;
414  delete compensationTable; compensationTable = NULL;
416 }
417 
418 
419 
420 
421 void ScannerFile4BitEncoded::ScanRate (float _scanRate)
422 {
423  ScannerFile::ScanRate (_scanRate);
424 }
425 
426 
427 
428 /*****************************************************************************/
429 /* Following routines are used for READING Scanner Files. */
430 /*****************************************************************************/
431 
432 
434 {
435  frameBufferLen = 0;
437  if (feof (file) != 0)
438  {
439  memset (frameBuffer, 0, frameBufferSize);
440  return 0;
441  }
442 
444  kkuint32 numScanLinesReadThisFrameBuffer = 0;
445  uchar* buffPtr = frameBuffer;
446  while ((feof (file) == 0) && (numScanLinesReadThisFrameBuffer < frameHeight))
447  {
448  GetNextScanLine (buffPtr, pixelsPerScanLine);
449  frameBufferLen += pixelsPerScanLine;
450  buffPtr += pixelsPerScanLine;
451  ++numScanLinesReadThisFrameBuffer;
452  }
453 
456  return numScanLinesReadThisFrameBuffer;
457 } /* ReadBufferFrame */
458 
459 
460 
462 {
463  uchar* scanLine = new uchar[pixelsPerScanLine];
464 
465  kkuint32 numScanLinesReadThisFrameBuffer = 0;
466  while ((feof (file) == 0) && (numScanLinesReadThisFrameBuffer < frameHeight))
467  {
468  GetNextScanLine (scanLine, pixelsPerScanLine);
469  ++numScanLinesReadThisFrameBuffer;
470  }
471 
472  delete[] scanLine;
473  scanLine = NULL;
474 
475  if (feof (file) != 0)
476  return -1;
477  else
478  return osFTELL (file);
479 } /* SkipToNextFrame */
480 
481 
482 
483 void ScannerFile4BitEncoded::ProcessTextBlock (const OpRec& rec)
484 {
485  OpRec rec2;
486 
487  kkuint32 recsRead = fread (&rec2, sizeof (rec2), 1, file);
488  if (recsRead < 1)
489  {
490  eof = true;
491  return;
492  }
493 
494  kkuint32 numTextBytes = 256 * rec.textBlock1.lenHighBits + rec2.textBlock2.lenLowBits;
495  char* textMsgPtr = new char[numTextBytes + 1]; // "+ 1" for terminating NULL Character.
496  kkuint32 textMsgLen = numTextBytes;
497 
498  recsRead = fread (textMsgPtr, 1, numTextBytes, file);
499  if (recsRead < numTextBytes)
500  eof = true;
501  else
502  {
503  textMsgPtr[recsRead] = 0;
504  ReportTextMsg (textMsgPtr, textMsgLen);
505  }
506  delete[] textMsgPtr; textMsgPtr = NULL;
507  textMsgLen = 0;
508 } /* ProcessTextBlock */
509 
510 
511 
512 void ScannerFile4BitEncoded::ProcessInstrumentDataWord (const OpRec& rec)
513 {
515 
518  kkuint32 recsRead = fread (&rec2, sizeof (rec2), 1, file);
519  if (recsRead < 1)
520  eof = true;
521  else
522  {
523  recsRead = fread (&rec3, sizeof (rec3), 1, file);
524  if (recsRead < 1)
525  eof = true;
526  else
527  ReportInstrumentDataWord (idNum, rec2.scanLineNum, rec3.word);
528  }
529 } /* ProcessInstrumentDataWord */
530 
531 
532 
533 
534 
535 void ScannerFile4BitEncoded::ProcessRawPixelRecs (kkuint16 numRawPixelRecs,
536  uchar* lineBuff,
537  kkuint32 lineBuffSize,
538  kkuint32& bufferLineLen
539  )
540 {
541  if (numRawPixelRecs > rawPixelRecBufferSize)
542  AllocateRawPixelRecBuffer (numRawPixelRecs + 30);
543 
544  size_t recsRead = fread (rawPixelRecBuffer, sizeof (RawPixelRec), numRawPixelRecs, file);
545  if (recsRead < numRawPixelRecs)
546  {
547  eof = true;
548  return;
549  }
550 
551  for (kkuint32 x = 0; x < numRawPixelRecs; ++x)
552  {
553  if (bufferLineLen < lineBuffSize) {lineBuff[bufferLineLen] = convTable4BitTo8Bit[rawPixelRecBuffer[x].pix0]; ++bufferLineLen;}
554  if (bufferLineLen < lineBuffSize) {lineBuff[bufferLineLen] = convTable4BitTo8Bit[rawPixelRecBuffer[x].pix1]; ++bufferLineLen;}
555  }
556 
557  return;
558 } /* ProcessRawPixelRecs */
559 
560 
561 
562 void ScannerFile4BitEncoded::GetNextScanLine (uchar* lineBuff,
563  kkuint32 lineBuffSize
564  )
565 {
566  bool eol = false;
567  uchar opCode = 0;
568  OpRec rec;
569  OpRec rec2;
570  kkuint32 recsRead = 0;
571 
572  kkuint32 bufferLineLen = 0;
573 
574  do
575  {
576  recsRead = fread (&rec, sizeof (rec), 1, file);
577  if (recsRead == 0)
578  {
579  break;
580  }
581 
582  opCode = rec.textBlock1.opCode;
583 
584  if (opCode == 0)
585  eol = true;
586 
587  else if (bufferLineLen >= lineBuffSize)
588  {
589  // Something has gone wrong, we should have encountered a eol opCode before this point; that is the
590  // length of the encoded line is exceeding the scan line length.
591  eol = true;
592  ungetc (rec.textChar, file);
593  break;
594  }
595 
596 
597  else if (opCode == 1)
598  ProcessTextBlock (rec);
599 
600  else if (opCode == 2)
601  ProcessInstrumentDataWord (rec);
602 
603  else if ((opCode >= 4) && (opCode <= 9))
604  {
605  // OpCode determines RunLen (4=2, 5=3, ... 9=7)
606  kkuint32 runLen = opCode - 2;
607  runLenChar = convTable4BitTo8Bit [rec.runLen.pixelValue];
608  kkuint32 newLineSize = bufferLineLen + runLen;
609 
610  if (newLineSize > lineBuffSize)
611  {
612  cerr << "ScannerFile4BitEncoded::GetNextScanLine ***ERROR*** Exceeding 'bufferLineLen'; ScanLine[" << nextScanLine << "]." << endl;
613  cerr << " newLineSize: " << newLineSize << endl;
614  }
615  else
616  {
617  memset (&(lineBuff[bufferLineLen]), runLenChar, runLen);
618  bufferLineLen = newLineSize;
619  }
620  }
621 
622  else if (opCode == 10) /* OpRecRun256Len1 */
623  {
624  recsRead = fread (&rec2, sizeof (rec2), 1, file);
625  if (recsRead < 1)
626  eol = true;
627  else
628  {
629  kkuint32 runLen = 1 + rec2.run256Len2.runLen;
630  kkuint32 newLineSize = bufferLineLen + runLen;
631  if (newLineSize > lineBuffSize)
632  {
633  cerr << "ScannerFile4BitEncoded::GetNextScanLine ***ERROR*** Exceeding 'bufferLineLen'; ScanLine[" << nextScanLine << "]." << endl;
634  }
635  else
636  {
637  uchar runLenChar = convTable4BitTo8Bit [rec.run256Len1.pixelValue];
638  memset (&(lineBuff[bufferLineLen]), runLenChar, runLen);
639  bufferLineLen = newLineSize;
640  }
641  }
642  }
643 
644  else if (opCode == 11)
645  {
646  if (bufferLineLen < lineBuffSize)
647  {
648  lineBuff[bufferLineLen] = convTable4BitTo8Bit[rec.raw1Pixel.pixelValue];
649  ++bufferLineLen;
650  }
651  else
652  {
653  cerr << "ScannerFile4BitEncoded::GetNextScanLine ***ERROR*** Exceeding 'bufferLineLen'; ScanLine[" << nextScanLine << "]." << endl;
654  }
655  }
656 
657  else if (opCode == 12)
658  {
659  kkuint16 numRawRecs = rec.raw32Pixels.len + 1; // We add 1 to 'numRawRecs' because '1' was subtracted out when written to Scanner File.
660  kkuint16 numRawPixels = numRawRecs * 2;
661  kkuint16 newBufferLineLen = bufferLineLen + numRawPixels;
662  if (newBufferLineLen > lineBuffSize)
663  {
664  cerr << "ScannerFile4BitEncoded::GetNextScanLine ***ERROR*** Exceeding 'bufferLineLen'; ScanLine[" << nextScanLine << "]." << endl;
665  }
666  ProcessRawPixelRecs (numRawRecs, lineBuff, lineBuffSize, bufferLineLen);
667  }
668 
669  else if (opCode == 13)
670  {
671  recsRead = fread (&rec2, sizeof (rec2), 1, file);
672  if (recsRead < 1)
673  {
674  eol = true;
675  eof = true;
676  }
677  else
678  {
679  kkuint16 numRawRecs = 1 + 16 * (kkuint16)(rec.raw513Pixels1.lenHigh) + (kkuint16)(rec2.raw513Pixels2.lenLow);
680  kkuint16 numRawPixels = 1 + 2 * numRawRecs;
681  kkuint16 newBufferLineLen = bufferLineLen + numRawPixels;
682  if (newBufferLineLen > lineBuffSize)
683  {
684  cerr << "ScannerFile4BitEncoded::GetNextScanLine ***ERROR*** Exceeding 'bufferLineLen'; ScanLine[" << nextScanLine << "]." << endl;
685  }
686 
687  if (bufferLineLen < lineBuffSize)
688  {
689  lineBuff[bufferLineLen] = convTable4BitTo8Bit[rec2.raw513Pixels2.pix0];
690  ++bufferLineLen;
691  }
692 
693  ProcessRawPixelRecs (numRawRecs, lineBuff, lineBuffSize, bufferLineLen);
694  }
695  }
696  } while (!eol);
697 
698 } /* GetNextScanLine */
699 
700 
701 
702 /*****************************************************************************/
703 /* Following routines are used for writing Scanner Files. */
704 /*****************************************************************************/
705 
707 {
709  //nextScanLineOffset = osFTELL (file);
710 
711  kkuint32 frameRow = 0;
712  uchar* framePtr = frameBuffer;
713  while (frameRow < frameBufferNextLine)
714  {
715  WriteNextScanLine (framePtr, pixelsPerScanLine);
716  framePtr += pixelsPerScanLine;
717  ++frameRow;
718  }
719 
722 } /* WriteBufferFrame*/
723 
724 
725 
726 void ScannerFile4BitEncoded::AddCurRunLenToOutputBuffer ()
727 {
728  OpRec rec;
729 
730  while (runLen > 0)
731  {
732  if (runLen == 1)
733  {
734  // We will treat this as a 1 pixel long raw string.
735  rec.raw1Pixel.opCode = 11;
736  rec.raw1Pixel.pixelValue = runLenChar;
737  *encodedBuffNext = rec;
738  ++encodedBuffNext;
739  runLen = 0;
740  }
741 
742  else if (runLen < 8)
743  {
744  rec.runLen.opCode = runLen + 2;
745  rec.runLen.pixelValue = runLenChar;
746  *encodedBuffNext = rec;
747  ++encodedBuffNext;
748  runLen = 0;
749  }
750 
751  else if (runLen < 257)
752  {
753  ushort encodedLen = runLen - 1;
754 
755  rec.run256Len1.opCode = 10;
756  rec.run256Len1.pixelValue = runLenChar;
757  *encodedBuffNext = rec;
758  ++encodedBuffNext;
759 
760  rec.run256Len2.runLen = encodedLen;
761  *encodedBuffNext = rec;
762  ++encodedBuffNext;
763  runLen = 0;
764  }
765 
766  else
767  {
768  rec.run256Len1.opCode = 10;
769  rec.run256Len1.pixelValue = runLenChar;
770  *encodedBuffNext = rec;
771  ++encodedBuffNext;
772 
773  rec.run256Len2.runLen = 255;
774  *encodedBuffNext = rec;
775  ++encodedBuffNext;
776  runLen -= 256;
777  }
778  }
779 } /* AddCurRunLenToOutputBuffer */
780 
781 
782 
783 void ScannerFile4BitEncoded::AddCurRawStrToOutputBuffer ()
784 {
785  OpRec rec;
786 
787  kkuint16 nextCp = 0;
788  kkuint16 len = rawStrLen;
789 
790  while (len > 0)
791  {
792  if (len < 2)
793  {
794  rec.raw1Pixel.opCode = 11;
795  rec.raw1Pixel.pixelValue = rawStr[nextCp];
796  *encodedBuffNext = rec;
797  ++encodedBuffNext;
798  len = 0;
799  ++nextCp;
800  }
801 
802  else if (len < 33)
803  {
804  ushort rawPixelRecsNeeded = (ushort)(len / 2) - 1; // We subtract 1 when writing; when reading back file will add back in 1.
805  rec.raw32Pixels.opCode = 12;
806  rec.raw32Pixels.len = rawPixelRecsNeeded;
807  *encodedBuffNext = rec;
808  ++encodedBuffNext;
809 
810  while (len > 1)
811  {
812  rec.rawPixels.pix0 = rawStr[nextCp]; ++nextCp;
813  rec.rawPixels.pix1 = rawStr[nextCp]; ++nextCp;
814  *encodedBuffNext = rec;
815  ++encodedBuffNext;
816  len -= 2;
817  }
818  }
819 
820  else
821  {
822  kkuint16 lenToProcess = Min ((kkuint16)513, len);
823  if ((lenToProcess % 2) > 0)
824  {
825  // Can only handle odd number of pixels.
826  --lenToProcess;
827  }
828 
829  kkuint16 numRawRecsNeeded = (lenToProcess - 1) / 2;
830  kkuint16 numRawRecsNeededEnc = numRawRecsNeeded - 1; // When reading back and decoding file will add back 1.
831  kkuint16 lenHigh = numRawRecsNeededEnc / 16;
832  kkuint16 lenLow = numRawRecsNeededEnc % 16;
833 
834  rec.raw513Pixels1.opCode = 13;
835  rec.raw513Pixels1.lenHigh = lenHigh;
836  *encodedBuffNext = rec;
837  ++encodedBuffNext;
838 
839  rec.raw513Pixels2.lenLow = lenLow;
840  rec.raw513Pixels2.pix0 = rawStr[nextCp];
841  *encodedBuffNext = rec;
842  ++encodedBuffNext;
843  ++nextCp;
844  --len;
845  --lenToProcess;
846 
847  while (lenToProcess > 1)
848  {
849  rec.rawPixels.pix0 = rawStr[nextCp]; ++nextCp;
850  rec.rawPixels.pix1 = rawStr[nextCp]; ++nextCp;
851  *encodedBuffNext = rec;
852  ++encodedBuffNext;
853  len -= 2;
854  lenToProcess -= 2;
855  }
856  }
857  }
858 
859  rawStrLen = 0;
860 } /* AddCurRawStrToOutputBuffer */
861 
862 
863 
864 void ScannerFile4BitEncoded::WriteNextScanLine (const uchar* buffer,
865  kkuint32 bufferLen
866  )
867 {
868  encodedBuffNext = encodedBuff;
869  encodedBuffLen = 0;
870  kkuint32 encodedBuffLeft = encodedBuffSize - encodedBuffLen;
871  if (bufferLen > (encodedBuffLeft - 10))
872  {
873  kkuint32 newEncodedBuffSise = bufferLen + 10;
874  ReSizeEncodedBuff (newEncodedBuffSise);
875  }
876 
877  curCompStatus = csNull;
878 
879  for (kkuint16 x = 0; x < bufferLen; ++x)
880  {
881  uchar nextCh = convTable8BitTo4Bit[buffer[x]];
882 
883  switch (curCompStatus)
884  {
885  case csNull:
886  {
887  runLen = 1;
888  runLenChar = nextCh;
889  curCompStatus = csRunLen;
890  }
891  break;
892 
893  case csRunLen:
894  {
895  if (nextCh == runLenChar)
896  {
897  ++runLen;
898  }
899  else if (runLen == 1)
900  {
901  rawStr[0] = runLenChar;
902  rawStr[1] = nextCh;
903  rawStrLen = 2;
904  runLen = 0;
905  curCompStatus = csRaw;
906  }
907  else
908  {
909  AddCurRunLenToOutputBuffer ();
910  runLenChar = nextCh;
911  runLen = 1;
912  }
913  }
914  break;
915 
916  case csRaw:
917  {
918  if (rawStrLen == 0)
919  {
920  rawStr[rawStrLen] = nextCh;
921  ++rawStrLen;
922  }
923 
924  else if (rawStr[rawStrLen - 1] != nextCh)
925  {
926  rawStr[rawStrLen] = nextCh;
927  ++rawStrLen;
928  }
929 
930  else
931  {
932  --rawStrLen;
933  if (rawStrLen > 0)
934  AddCurRawStrToOutputBuffer ();
935 
936  runLen = 2;
937  runLenChar = nextCh;
938  curCompStatus = csRunLen;
939  }
940  }
941  break;
942  }
943  }
944 
945  if (curCompStatus == csRunLen)
946  AddCurRunLenToOutputBuffer ();
947 
948  if (curCompStatus == csRaw)
949  AddCurRawStrToOutputBuffer ();
950 
951  OpRec rec;
952  rec.endOfScanLine.opCode = 0;
953  rec.endOfScanLine.filler = 0;
954  *encodedBuffNext = rec;
955  ++encodedBuffNext;
956 
957  encodedBuffLen = encodedBuffNext - encodedBuff;
958  fwrite (encodedBuff, sizeof (OpRec), encodedBuffLen, file);
960 
961  /**@todo Write out OutputBuffer; */
962 
963 } /* WriteNextScanLine */
964 
965 
966 
967 
968 
970  kkuint32 txtBlockLen
971  )
972 {
973  if (txtBlockLen > (encodedBuffSize - 10))
974  {
975  kkuint32 newEncodedBuffSise = txtBlockLen + 10;
976  ReSizeEncodedBuff (newEncodedBuffSise);
977  }
978 
979  encodedBuffNext = encodedBuff;
980  encodedBuffLen = 0;
981  kkint32 charsLeft = txtBlockLen;
982  const uchar* txtBlockPtr = txtBlock;
983  while (charsLeft > 0)
984  {
985  kkint32 charsToWrite = Min (2048, charsLeft);
986  OpRec rec;
987 
988  rec.textBlock1.opCode = 1;
989  rec.textBlock1.endOfText = (charsToWrite < charsLeft) ? 0 : 1;
990  rec.textBlock1.lenHighBits = charsToWrite / 256;
991  *encodedBuffNext = rec;
992  ++encodedBuffNext;
993 
994  encodedBuffNext->textBlock2.lenLowBits = charsToWrite % 256;
995  ++encodedBuffNext;
996 
997  memcpy (encodedBuffNext, txtBlockPtr, charsToWrite);
998 
999  charsLeft -= charsToWrite;
1000  txtBlockPtr += charsToWrite;
1001  encodedBuffNext += charsToWrite;
1002  }
1003 
1004  fwrite (encodedBuff, sizeof (OpRec), encodedBuffLen, file);
1006 } /* WriteTextBlock */
1007 
1008 
1009 /*
1010 
1011 void ScannerFile4BitEncoded::WriteInstrumentDataWord (uchar idNum,
1012  kkuint32 scanLineNum,
1013  WordFormat32Bits dataWord
1014  )
1015 {
1016  OpRecInstrumentDataWord1 r1;
1017  r1.opCode = 2;
1018  r1.idNum = idNum;
1019  fwrite (&r1, sizeof (r1), 1, file);
1020 
1021  OpRecInstrumentDataWord2 r2;
1022  r2.scanLineNum = scanLineNum;
1023  fwrite (&r2, sizeof (r2), 1, file);
1024 
1025  OpRecInstrumentDataWord3 r3;
1026  r3.word = dataWord;
1027  fwrite (&r3, sizeof (r3), 1, file);
1028 
1029  fileSizeInBytes = osFTELL (file);
1030 }
1031 */
__int16 kkint16
16 bit signed integer.
Definition: KKBaseTypes.h:85
kkint64 frameBufferFileOffsetLast
Definition: ScannerFile.h:427
kkint64 frameBufferFileOffsetNext
Definition: ScannerFile.h:429
ScannerFile4BitEncoded(const KKStr &_fileName, RunLog &_log)
kkint64 fileSizeInBytes
Definition: ScannerFile.h:396
__int32 kkint32
Definition: KKBaseTypes.h:88
virtual kkint64 SkipToNextFrame()
Skip to start of next frame returning back byte offset of that frame.
Structure used to break 32 bit word into different formats;.
Definition: KKBaseTypes.h:283
kkint64 osFTELL(FILE *f)
Calls the appropriate 64 bit function for operating system.
Definition: OSservices.cpp:93
static const uchar * CompensationTable()
unsigned __int16 kkuint16
16 bit unsigned integer.
Definition: KKBaseTypes.h:86
kkuint32 frameBufferLen
Definition: ScannerFile.h:435
unsigned __int32 kkuint32
Definition: KKBaseTypes.h:89
virtual void ScanRate(float _scanRate)
__int64 kkint64
Definition: KKBaseTypes.h:90
KKTHread * KKTHreadPtr
virtual void WriteBufferFrame()
Write the contents of &#39;frameBuffer&#39; to he end of the scanner file.
unsigned char uchar
Unsigned character.
Definition: KKBaseTypes.h:77
static KKStr Concat(const std::vector< std::string > &values)
Concatenates the list of &#39;std::string&#39; strings.
Definition: KKStr.cpp:1082
Contains Classes that are specific to Cameras physical characteristics.
unsigned short ushort
Unsigned short.
Definition: KKBaseTypes.h:79
kkuint32 ReadBufferFrame()
Writes a 32 bit number into the Scanner File Stream at current location.
kkuint32 frameBufferNextLine
Definition: ScannerFile.h:441
Implements a 4 bit Encoded format.
kkuint32 pixelsPerScanLine
Definition: ScannerFile.h:407
Used for logging messages.
Definition: RunLog.h:49
ScannerFile4BitEncoded(const KKStr &_fileName, kkuint32 _pixelsPerScanLine, kkuint32 _frameHeight, RunLog &_log)
ScannerFile(const KKStr &_fileName, kkuint32 _pixelsPerScanLine, kkuint32 _frameHeight, RunLog &_log)
Maintains one instance of a GoalKeeper object that can be used anywhere in the application.
ScannerFile(const KKStr &_fileName, RunLog &_log)
Definition: ScannerFile.cpp:40
virtual void WriteTextBlock(const uchar *txtBlock, kkuint32 txtBlockLen)