1#include "./AOI_Screener.h"
2#include "../GInstance.h"
3#include <ACPL/SwapStream.h>
6using namespace aur::PDF;
7using namespace aur::ACPL;
26class AOI_Screener::Internal
33 const uint8_t* inputData;
34 uint32_t bytesPerPixel;
35 const uint16_t* transferCurve;
36 int32_t maxPixelWidth;
41 uint16_t mLinCurve[256];
47 uint16_t* mCellHandle;
60 int16_t mTreshHold[kMaxDotSizes];
61 int16_t mWeight[kMaxDotSizes];
62 const int16_t* mThreshold;
63 int16_t mThresholdArray[1000];
64 void (*mDo)( Internal* );
66 Internal(
const Params&, uint16_t*, uint32_t, uint8_t,
const float* );
68 void StartPage( int32_t );
69 void Do(
const uint8_t*, uint8_t* );
70 void SetNoiseFactor(
int );
72 static void LeftToRight2( Internal* );
73 static void RightToLeft2( Internal* );
74 static void LeftToRight3( Internal* );
75 static void RightToLeft3( Internal* );
76 static void LeftToRight4( Internal* );
77 static void RightToLeft4( Internal* );
78 static void LeftToRight6( Internal* );
79 static void RightToLeft6( Internal* );
80 static void LeftToRight16( Internal* );
81 static void RightToLeft16( Internal* );
82 static void LeftToRight256( Internal* );
83 static void RightToLeft256( Internal* );
85 static void LeftToRight2_AntiClog( Internal* );
86 static void RightToLeft2_AntiClog1( Internal* );
87 static void RightToLeft2_AntiClog2( Internal* );
90const int16_t kThresholdArray[1000] =
92-30, -22, 17, -1, 3, -16, -27, 12, 12, 28, -6, 2, 22, -28, -27, 2, 11, -30, -6, -26, -4, 12, 6, 28, 23,
932, -25, 10, -4, 13, 27, 17, -14, -27, 16, -9, 9, 17, 32, -7, -15, 31, 15, 17, 10, -26, 9, 25, -13, -3,
9418, 0, -15, -13, -8, -20, 1, 26, 27, -27, 26, 1, 2, -10, 32, 1, -13, -25, 29, -26, 1, -6, -13, 27, 2,
95-1, 29, -27, 17, 18, 21, -22, -29, 13, 24, 9, 16, 15, 32, 25, -16, -11, -8, 1, 6, 23, -4, 22, -13, -4,
963, -1, -12, -19, -21, 5, 20, -28, 3, 1, 30, 16, 4, 26, 8, 22, -20, -17, 14, -22, -25, -13, -30, -4, -29,
9714, 29, -15, -20, -11, 24, 9, -22, 11, -7, -7, 0, -22, 5, 22, 5, 29, 3, -22, 30, -5, -22, 4, -15, 0,
98-2, 29, -23, -19, -11, 8, -23, 9, 7, 19, -16, -1, -7, -18, -30, 25, -4, -22, 28, -5, -23, 24, -26, -21, -27,
99-8, -15, -23, 18, -2, -9, -3, 19, 27, 9, -18, 11, 26, -15, 23, -1, 0, 6, 20, 16, -2, 28, 8, -3, 20,
10012, 12, 31, 29, 22, -13, 2, 0, -25, -5, 4, 24, -3, 14, 23, 13, 19, 13, 15, -30, 24, 1, -2, -27, 13,
1010, 10, 11, -19, 26, 23, 24, 2, -23, -3, 31, -18, -3, -11, 0, 24, -3, -2, 19, -8, -18, 31, -22, 8, 7,
102-31, -31, 17, 14, -11, -5, 11, 11, -18, 21, 13, 21, -25, -26, 16, 8, -18, -18, -26, -7, 28, 28, -7, -14, 12,
103-13, 17, 18, -4, -13, -19, -31, -19, 30, -16, 20, -23, -6, 6, -20, 21, -21, 31, -15, -17, -25, -17, 8, 12, 18,
10412, 16, 10, 8, -28, 6, -17, -11, 12, -24, 16, 1, 3, 5, -10, 12, -22, -21, 0, 23, 20, 3, 15, -11, -23,
1051, -12, 5, 1, -4, -15, -8, -6, -3, -1, -7, -14, -26, -8, -15, 10, 11, 0, 14, 14, 28, -2, 28, -11, -2,
1061, 10, -6, 6, 31, -22, 10, -9, 2, 1, 21, -31, -14, 9, 2, 26, -14, 30, -16, 22, 12, -2, 20, -30, -21,
10713, 13, -4, 5, 16, 31, 12, -14, 16, -21, -31, 0, -26, -21, 25, 18, 15, -4, -31, 5, 1, -27, 2, -7, -18,
108-7, 8, 10, 13, 2, -14, 20, -8, 11, -12, -31, -25, 1, 17, -17, -28, -27, -21, 14, -12, -28, -1, -2, 1, -3,
109-22, -13, 21, 12, 4, 11, -10, -28, 31, 2, -31, 22, -30, -7, 0, 4, 15, 11, 2, -29, -24, 30, -19, -9, 7,
1106, -23, 3, 29, -9, 21, 30, -15, -15, -4, 20, 25, -16, 16, 12, -3, -15, 10, -24, -18, -24, 3, -31, -20, 6,
111-4, -26, 11, -7, 21, -24, 30, -30, -26, 0, 17, 27, -15, -8, 17, 0, 15, 11, 11, 16, -29, -17, -17, 4, 9,
1127, -8, -17, -17, 9, -21, 15, -21, -28, 10, -24, 28, -1, 7, 26, -30, 5, 14, 0, -28, -3, 1, 17, -27, -3,
11330, -2, -10, -3, 15, -18, -21, -8, 28, 29, -15, -27, -24, 1, -21, 1, -25, 21, -8, -4, -11, 13, 4, 23, 16,
11421, 12, -7, 27, 6, -8, 2, -2, -6, -16, -26, -5, -1, -13, -25, -18, 19, 1, 10, 23, -16, 13, -15, -7, -26,
115-2, -17, 18, 0, -31, -14, 10, -4, -20, 29, -23, 18, 28, -21, 6, -27, -9, -13, 0, 20, 21, 14, -10, 19, 8,
116-29, -29, -22, 17, -28, 1, 27, -17, -18, -26, 12, 13, 0, -15, 13, -7, -19, -17, -4, -1, 23, 30, -3, -29, 1,
117-29, 16, 5, 20, -10, -17, 2, -4, -6, 31, 29, 22, 23, -12, -22, 31, 8, -2, 27, 12, 20, 2, 4, -21, 28,
11820, -22, -29, -10, -24, -25, 1, -30, 3, 22, 1, 11, 15, 12, -30, -19, 10, -9, -27, -22, 26, -17, -7, 5, -21,
119-30, 12, 16, 13, -27, 5, 27, 27, -4, 0, 21, 26, 6, 14, 1, 0, -21, 30, 4, -14, 2, 12, 10, -25, 3,
1207, 10, 0, 4, 5, -3, -22, 0, 14, -29, -28, 1, -11, -29, -16, -25, -7, 3, 6, 7, 27, 17, 0, 0, 9,
12112, -5, 0, -1, 13, 2, -14, 6, -14, 13, 1, 28, -16, -5, 6, 18, 26, 11, 20, 1, -17, -22, 25, -15, 9,
122-31, 27, -14, 22, -14, 28, 0, -24, -5, 12, -4, -25, 17, -25, -3, -9, -12, 16, -10, -10, -28, 4, 0, -19, -24,
12330, 23, 0, -8, 19, -21, -21, -28, -22, -2, -7, 24, -4, -5, 9, -12, -28, 20, 25, 26, 25, 17, -21, 4, -29,
12419, 1, 23, -14, 23, 5, -7, 19, 1, 28, -5, 5, 15, 24, -10, -19, 15, 14, 24, -27, 13, 24, -8, -26, -21,
125-5, -25, 11, 4, 20, 24, 17, 8, 25, 24, 0, -24, -7, -7, 12, -24, -27, -22, -1, 13, -16, -6, 30, 8, 11,
12626, -8, 22, 18, -4, -27, 0, -1, -3, 0, 15, 27, -12, -22, -24, -26, 30, -5, -16, 29, 21, -19, -23, -19, -10,
1274, -3, 5, -4, -8, -7, 6, -4, -22, 10, 31, 12, -6, 22, 20, 18, -8, -31, -1, 8, 9, 9, 19, -7, -9,
128-7, -10, 12, -22, -13, 10, 22, -11, -22, 6, -31, 26, -7, 1, -9, -15, -13, 21, -24, 8, -28, -2, -7, -22, 16,
12910, -31, 18, 3, -13, -5, -11, 0, 14, 21, -17, -2, -8, -28, -27, -19, 4, 21, -4, 21, -13, -20, -9, 27, 5,
130-8, -2, 8, 28, -6, -28, -3, 6, 15, 23, -23, -25, 10, 21, 5, 10, 30, -30, 26, -19, 29, 1, -14, 14, 5,
13121, 21, 10, 14, 9, -9, 2, 10, -11, 23, -3, 26, -14, 28, -24, -5, 21, 29, -10, 1, 2, 20, 27, 10, -16
133const int16_t* gTresholdArray = kThresholdArray;
136#define MOD_CELLSIZE( x ) ( x & 0x3FF )
137#define MUL_CELLSIZE( x ) ( x << 10 )
138#define kTreshold 1024
139#define kTransferTo8Bit 7
140#define FloydSteinberg 0
141#define kTransferResolution 32768
143static const int16_t kMaxPixelWeight = ( kTransferResolution >> (kTransferTo8Bit-3) ) - 1;
145AOI_Screener::Internal::Internal(
const Params& params, uint16_t* inCell, uint32_t offset, uint8_t levels,
const float* dotSize )
153 for( i = levels; i > 0; --i )
154 mWeight[i-1] = int16_t( dotSize[ levels-i-1 ] * kMaxPixelWeight + 0.5f );
155 mWeight[ levels-1 ] = 0;
161 for( i = 0; i < levels-1; ++i )
163 mTreshHold[i] = ( mWeight[i] + mWeight[i+1] ) / 2;
164 mTreshHold[i] -= ( mWeight[ levels - 2 ] * 2 ) / 5;
166 mTreshHold[ levels-1 ] = 0;
168 int32_t pixels = mParam.maxPixelWidth + 6;
169 mHorBuffer =
new EDErr[ pixels ];
170 ::memset( mHorBuffer, 0,
sizeof(EDErr) * pixels );
176 ::snprintf( name,
sizeof(name),
"%dx%d.cell",
int(CELLSIZE),
int(CELLSIZE) );
177 spec.Make( Instance::sDefault->ResourceDirectory(), name );
179 FileStream cellStream( spec, eReadPermission );
181 SwapStream cellStream( spec, eReadPermission );
183 mCellHandle =
new uint16_t[ CELLSIZE * CELLSIZE ];
184 uint16_t* c = mCellHandle;
185 for( uint32_t j = 0; j != CELLSIZE * CELLSIZE; ++j )
192 for(
int j = 0; j != 256; ++j )
194 mLinCurve[j] = mParam.transferCurve[j] >> 1;
195 if( mLinCurve[j] == 0 )
198 mBalance[j] = int( 64 / (
double( mLinCurve[j] ) / kTransferResolution ) );
200 mParam.transferCurve = mLinCurve;
203 mThreshold = mThresholdArray;
206AOI_Screener::Internal::~Internal()
209 delete[] mCellHandle;
212void AOI_Screener::Internal::SetNoiseFactor(
int f )
214 for( uint32_t i = 0; i != 1000; ++i )
215 mThresholdArray[i] = kThresholdArray[i] * f;
221void AOI_Screener::Internal::StartPage( int32_t w )
225 int32_t width = mWidth;
241 mDo = LeftToRight2_AntiClog;
242 mRightOff = width >> 3;
244 mRightMask = 128 >> ( ( width % 8 ) - 1 );
257 mRightOff = width >> 2;
259 mRightMask = 0x40 >> ( ( ( width % 4 ) - 1 ) * 2 );
276 mRightOff = width >> 1;
287 mDo = LeftToRight256;
288 mRightOff = width - 1;
302void AOI_Screener::Internal::Do(
const uint8_t* inData, uint8_t* outData )
304 mParam.inputData = inData;
305 mParam.rawBuffer = outData;
306 ::memset( outData, 0, mRightOff );
310void AOI_Screener::Internal::LeftToRight2( Internal* obj )
312 const uint8_t* src = obj->mParam.inputData;
313 uint8_t* raw = obj->mParam.rawBuffer;
314 int32_t bpp = obj->mParam.bytesPerPixel;
315 uint8_t rawMask = 0x80;
316 EDErr* horBuf = obj->mHorBuffer + 3;
317 EDErr theError = *horBuf;
318 uint16_t* cellRow = &obj->mCell[ MUL_CELLSIZE( obj->mYInCell ) ];
322 for( int32_t x = 0; x != obj->mWidth; ++x, src += bpp )
324 threshold = *obj->mThreshold + kTreshold;
325 source = obj->mParam.transferCurve[ *src ];
326 theError = EDErr( ( int32_t( theError ) + source ) >> 4 );
327 if( source && source >= cellRow[ MOD_CELLSIZE( x ) ] )
328 threshold -= obj->mBalance[ *src ];
330 if( theError >= threshold )
333 theError -= kMaxPixelWeight;
336 if( obj->mThreshold == obj->mThresholdArray )
337 obj->mThreshold += 999;
341 if( ( rawMask >>= 1 ) == 0 )
347 horBuf[-2] += ( theError << 1 ) + theError;
348 horBuf[-1] += ( theError << 2 ) + theError;
351 theError = ( ( theError << 3 ) - theError ) + *horBuf;
355 horBuf[-3] += theError;
356 horBuf[-1] += theError;
365 obj->mDo = RightToLeft2;
366 if( ++obj->mYInCell == CELLSIZE )
370void AOI_Screener::Internal::RightToLeft2( Internal* obj )
372 int32_t bpp = obj->mParam.bytesPerPixel;
373 uint8_t* raw = obj->mParam.rawBuffer + obj->mRightOff;
374 const uint8_t* src = obj->mParam.inputData + bpp * ( obj->mWidth - 1 );
375 EDErr* horBuf = obj->mHorBuffer + 3 + obj->mWidth - 1;
376 EDErr theError = *horBuf;
377 uint8_t rawMask = obj->mRightMask;
378 uint16_t* cellRow = &obj->mCell[ MUL_CELLSIZE( obj->mYInCell ) ];
382 for( int32_t x = obj->mWidth - 1; x >= 0 ; --x, src -= bpp )
384 threshold = *obj->mThreshold + kTreshold;
385 source = obj->mParam.transferCurve[ *src ];
386 theError = EDErr( ( int32_t( theError ) + source ) >> 4 );
387 if( source && source >= cellRow[ MOD_CELLSIZE( x ) ] )
388 threshold -= obj->mBalance[ *src ];
390 if( theError >= threshold )
393 theError -= kMaxPixelWeight;
396 if( obj->mThreshold == obj->mThresholdArray )
397 obj->mThreshold += 999;
401 if( ( rawMask <<= 1 ) == 0 )
408 horBuf[2] += ( theError << 1 ) + theError;
409 horBuf[1] += ( theError << 2 ) + theError;
412 theError = ( ( theError << 3 ) - theError ) + *horBuf;
416 horBuf[3] += theError;
417 horBuf[1] += theError;
426 obj->mDo = LeftToRight2;
427 if( ++obj->mYInCell == CELLSIZE )
431void AOI_Screener::Internal::LeftToRight3( Internal* obj )
433 const uint8_t* src = obj->mParam.inputData;
434 uint8_t* raw = obj->mParam.rawBuffer;
435 int32_t bpp = obj->mParam.bytesPerPixel;
436 uint8_t rawMask = 0x40;
437 EDErr* horBuf = obj->mHorBuffer + 3;
438 EDErr theError = *horBuf;
439 EDErr treshHold0 = obj->mTreshHold[0];
440 int16_t weight0 = obj->mWeight[0];
441 EDErr treshHold1 = obj->mTreshHold[1];
442 int16_t weight1 = obj->mWeight[1];
444 uint16_t* cellRow = &obj->mCell[ MUL_CELLSIZE( obj->mYInCell ) ];
447 for( int32_t x = 0; x != obj->mWidth ; ++x, src += bpp )
449 randThreshold = *obj->mThreshold;
450 if( obj->mThreshold == obj->mThresholdArray )
451 obj->mThreshold += 999;
454 source = obj->mParam.transferCurve[ *src ];
455 theError = EDErr( ( int32_t( theError ) + source ) >> 4 );
456 if( theError >= randThreshold + treshHold0 )
458 *raw |= rawMask << 1;
463 if( source && source >= cellRow[ MOD_CELLSIZE( x ) ] )
464 randThreshold -= obj->mBalance[ *src ];
465 if( theError >= randThreshold + treshHold1 )
472 if( ( rawMask >>= 2 ) == 0 )
479 horBuf[-3] += theError;
480 horBuf[-1] += theError;
488 obj->mDo = RightToLeft3;
489 if( ++obj->mYInCell == CELLSIZE )
493void AOI_Screener::Internal::RightToLeft3( Internal* obj )
495 uint8_t* raw = obj->mParam.rawBuffer + obj->mRightOff;
496 int32_t bpp = obj->mParam.bytesPerPixel;
497 const uint8_t* src = obj->mParam.inputData + bpp * ( obj->mWidth - 1 );
498 EDErr* horBuf = obj->mHorBuffer + 3 + obj->mWidth - 1;
499 EDErr theError = *horBuf;
500 uint8_t rawMask = obj->mRightMask;
501 EDErr treshHold0 = obj->mTreshHold[0];
502 int16_t weight0 = obj->mWeight[0];
503 EDErr treshHold1 = obj->mTreshHold[1];
504 int16_t weight1 = obj->mWeight[1];
506 uint16_t* cellRow = &obj->mCell[ MUL_CELLSIZE( obj->mYInCell ) ];
510 for( int32_t x = obj->mWidth - 1; x >= 0 ; --x, src -= bpp )
512 randThreshold = *obj->mThreshold;
513 if( obj->mThreshold == obj->mThresholdArray )
514 obj->mThreshold += 999;
517 source = obj->mParam.transferCurve[ *src ];
518 theError = EDErr( ( int32_t( theError ) + source ) >> 4 );
519 if( theError >= randThreshold + treshHold0 )
521 *raw |= rawMask << 1;
526 if( source && source >= cellRow[ MOD_CELLSIZE( x ) ] )
527 randThreshold -= obj->mBalance[ *src ];
528 if( theError >= randThreshold + treshHold1 )
535 if( ( rawMask <<= 2 ) == 0 )
542 horBuf[3] += theError;
543 horBuf[1] += theError;
551 obj->mDo = LeftToRight3;
552 if( ++obj->mYInCell == CELLSIZE )
556void AOI_Screener::Internal::LeftToRight4( Internal* obj )
558 const uint8_t* src = obj->mParam.inputData;
559 uint8_t* raw = obj->mParam.rawBuffer;
560 int32_t bpp = obj->mParam.bytesPerPixel;
561 uint8_t rawMask = 0x40;
562 EDErr* horBuf = obj->mHorBuffer + 3;
563 EDErr theError = *horBuf;
564 EDErr treshHold0 = obj->mTreshHold[0];
565 EDErr treshHold1 = obj->mTreshHold[1];
566 EDErr treshHold2 = obj->mTreshHold[2];
568 uint16_t* cellRow = &obj->mCell[ MUL_CELLSIZE( obj->mYInCell ) ];
571 for( int32_t x = 0; x != obj->mWidth; ++x, src += bpp )
573 randThreshold = *obj->mThreshold;
574 if( obj->mThreshold == obj->mThresholdArray )
575 obj->mThreshold += 999;
579 source = obj->mParam.transferCurve[ *src ];
580 theError = EDErr( ( int32_t( theError ) + source ) >> 4 );
581 if( theError >= randThreshold + treshHold0 )
583 *raw |= rawMask | ( rawMask << 1 );
584 theError -= obj->mWeight[0];
586 else if( theError >= randThreshold + treshHold1 )
588 *raw |= rawMask << 1;
589 theError -= obj->mWeight[1];
593 if( source && source >= cellRow[ MOD_CELLSIZE( x ) ] )
594 randThreshold -= obj->mBalance[ *src ];
595 if( theError >= randThreshold + treshHold2 )
598 theError -= obj->mWeight[2];
603 horBuf[-3] += theError;
604 horBuf[-1] += theError;
612 if( ( rawMask >>= 2 ) == 0 )
618 obj->mDo = RightToLeft4;
619 if( ++obj->mYInCell == CELLSIZE )
623void AOI_Screener::Internal::RightToLeft4( Internal* obj )
625 uint8_t* raw = obj->mParam.rawBuffer + obj->mRightOff;
626 int32_t bpp = obj->mParam.bytesPerPixel;
627 const uint8_t* src = obj->mParam.inputData + bpp * ( obj->mWidth - 1 );
628 EDErr* horBuf = obj->mHorBuffer + 3 + obj->mWidth - 1;
629 EDErr theError = *horBuf;
630 uint8_t rawMask = obj->mRightMask;
631 EDErr treshHold0 = obj->mTreshHold[0];
632 EDErr treshHold1 = obj->mTreshHold[1];
633 EDErr treshHold2 = obj->mTreshHold[2];
635 uint16_t* cellRow = &obj->mCell[ MUL_CELLSIZE( obj->mYInCell ) ];
638 for( int32_t x = obj->mWidth - 1; x >= 0 ; --x, src -= bpp )
640 randThreshold = *obj->mThreshold;
641 if( obj->mThreshold == obj->mThresholdArray )
642 obj->mThreshold += 999;
646 source = obj->mParam.transferCurve[ *src ];
647 theError = EDErr( ( int32_t( theError ) + source ) >> 4 );
648 if( theError >= randThreshold + treshHold0 )
650 *raw |= rawMask | ( rawMask << 1 );
651 theError -= obj->mWeight[0];
653 else if( theError >= randThreshold + treshHold1 )
655 *raw |= rawMask << 1;
656 theError -= obj->mWeight[1];
660 if( source && source >= cellRow[ MOD_CELLSIZE( x ) ] )
661 randThreshold -= obj->mBalance[ *src ];
662 if( theError >= randThreshold + treshHold2 )
665 theError -= obj->mWeight[2];
670 horBuf[3] += theError;
671 horBuf[1] += theError;
679 if( ( rawMask <<= 2 ) == 0 )
685 obj->mDo = LeftToRight4;
686 if( ++obj->mYInCell == CELLSIZE )
690void AOI_Screener::Internal::LeftToRight6( Internal* obj )
692 const uint8_t* src = obj->mParam.inputData;
693 uint8_t* raw = obj->mParam.rawBuffer;
694 int32_t bpp = obj->mParam.bytesPerPixel;
695 const int rawShifts[] = { 5, 2, 0, 4, 1, 0, 3, 0 };
696 const int rawRestShifts[] = { 0, 0, 1, 0, 0, 2, 0, 0 };
697 uint8_t shiftIndex = 0;
700 int maxLevels = obj->mLevels - 1;
702 EDErr* horBuf = obj->mHorBuffer + 3;
703 EDErr theError = *horBuf;
704 uint16_t* cellRow = &obj->mCell[ MUL_CELLSIZE( obj->mYInCell ) ];
707 for( int32_t x = 0; x != obj->mWidth; ++x, src += bpp )
709 randThreshold = *obj->mThreshold;
710 if( obj->mThreshold == obj->mThresholdArray )
711 obj->mThreshold += 999;
715 source = obj->mParam.transferCurve[ *src ];
716 theError = EDErr( ( int32_t( theError ) + source ) >> 4 );
717 for( l = 0; l != maxLevels; ++l )
719 if( source && l == maxLevels-1 && source >= cellRow[ MOD_CELLSIZE( x ) ] )
720 randThreshold -= obj->mBalance[ *src ];
721 if( theError >= randThreshold + obj->mTreshHold[l] )
723 if( rawShifts[ shiftIndex ] > 0 )
724 *raw |= ( maxLevels - l ) << rawShifts[ shiftIndex ];
727 *raw |= ( maxLevels - l ) >> rawRestShifts[ shiftIndex ];
728 rest = ( maxLevels - l ) & ( ( 1 << rawRestShifts[ shiftIndex ] ) - 1 );
730 theError -= obj->mWeight[l];
736 horBuf[-3] += theError;
737 horBuf[-1] += theError;
746 if( shiftIndex == 3 || shiftIndex == 6 || shiftIndex == 8 )
748 *(++raw) = rest << ( 8 - rawRestShifts[ shiftIndex - 1 ] );
749 if( shiftIndex == 8 )
754 obj->mRightOff = int32_t( raw - obj->mParam.rawBuffer );
755 obj->mRightMask = shiftIndex;
756 obj->mDo = RightToLeft6;
757 if( ++obj->mYInCell == CELLSIZE )
761void AOI_Screener::Internal::RightToLeft6( Internal* obj )
763 uint8_t* raw = obj->mParam.rawBuffer + obj->mRightOff;
764 int32_t bpp = obj->mParam.bytesPerPixel;
765 const uint8_t* src = obj->mParam.inputData + bpp * ( obj->mWidth - 1 );
766 const int rawShifts[] = { 5, 2, 0, 4, 1, 0, 3, 0 };
767 const int rawRestShifts[] = { 0, 0, 1, 0, 0, 2, 0, 8 };
768 uint8_t shiftIndex = obj->mRightMask;
771 int maxLevels = obj->mLevels - 1;
773 EDErr* horBuf = obj->mHorBuffer + 3 + obj->mWidth - 1;
774 EDErr theError = *horBuf;
775 uint16_t* cellRow = &obj->mCell[ MUL_CELLSIZE( obj->mYInCell ) ];
778 if( --shiftIndex > 7 )
780 for( int32_t x = obj->mWidth - 1; x >= 0 ; --x, src -= bpp )
782 randThreshold = *obj->mThreshold;
783 if( obj->mThreshold == obj->mThresholdArray )
784 obj->mThreshold += 999;
788 source = obj->mParam.transferCurve[ *src ];
789 theError = EDErr( ( int32_t( theError ) + source ) >> 4 );
790 for( l = 0; l != maxLevels; ++l )
792 if( source && l == maxLevels-1 && source >= cellRow[ MOD_CELLSIZE( x ) ] )
793 randThreshold -= obj->mBalance[ *src ];
794 if( theError >= randThreshold + obj->mTreshHold[l] )
796 if( rawShifts[ shiftIndex ] > 0 )
797 *raw |= ( maxLevels - l ) << rawShifts[ shiftIndex ];
800 *raw |= ( maxLevels - l ) << ( 8 - rawRestShifts[ shiftIndex ] );
801 rest = ( maxLevels - l ) >> rawRestShifts[ shiftIndex ];
803 theError -= obj->mWeight[l];
809 horBuf[3] += theError;
810 horBuf[1] += theError;
819 if( shiftIndex == 1 || shiftIndex == 4 || shiftIndex == uint8_t( -1 ) )
821 if( raw - 1 >= obj->mParam.rawBuffer )
823 if( shiftIndex == uint8_t( -1 ) )
828 obj->mDo = LeftToRight6;
829 if( ++obj->mYInCell == CELLSIZE )
833void AOI_Screener::Internal::LeftToRight16( Internal* obj )
835 const uint8_t* src = obj->mParam.inputData;
836 uint8_t* raw = obj->mParam.rawBuffer;
837 int32_t bpp = obj->mParam.bytesPerPixel;
840 int maxLevels = obj->mLevels-1;
842 EDErr* horBuf = obj->mHorBuffer + 3;
843 EDErr theError = *horBuf;
844 uint16_t* cellRow = &obj->mCell[ MUL_CELLSIZE( obj->mYInCell ) ];
847 for( int32_t x = 0; x != obj->mWidth; ++x, src += bpp )
849 randThreshold = *obj->mThreshold;
850 if( obj->mThreshold == obj->mThresholdArray )
851 obj->mThreshold += 999;
855 source = obj->mParam.transferCurve[ *src ];
856 theError = EDErr( ( int32_t( theError ) + source ) >> 4 );
857 for( l = 0; l != maxLevels; ++l )
859 if( source && l == maxLevels-1 && source >= cellRow[ MOD_CELLSIZE( x ) ] )
860 randThreshold -= obj->mBalance[ *src ];
861 if( theError >= randThreshold + obj->mTreshHold[l] )
863 *raw |= ( maxLevels - l ) << rawShift;
864 theError -= obj->mWeight[l];
870 horBuf[-3] += theError;
871 horBuf[-1] += theError;
887 obj->mDo = RightToLeft16;
888 if( ++obj->mYInCell == CELLSIZE )
892void AOI_Screener::Internal::RightToLeft16( Internal* obj )
894 uint8_t* raw = obj->mParam.rawBuffer + obj->mRightOff;
895 int32_t bpp = obj->mParam.bytesPerPixel;
896 const uint8_t* src = obj->mParam.inputData + bpp * ( obj->mWidth - 1 );
897 int rawShift = obj->mRightMask;
899 int maxLevels = obj->mLevels-1;
901 EDErr* horBuf = obj->mHorBuffer + 3 + obj->mWidth - 1;
902 EDErr theError = *horBuf;
903 uint16_t* cellRow = &obj->mCell[ MUL_CELLSIZE( obj->mYInCell ) ];
906 for( int32_t x = obj->mWidth - 1; x >= 0 ; --x, src -= bpp )
908 randThreshold = *obj->mThreshold;
909 if( obj->mThreshold == obj->mThresholdArray )
910 obj->mThreshold += 999;
914 source = obj->mParam.transferCurve[ *src ];
915 theError = EDErr( ( int32_t( theError ) + source ) >> 4 );
916 for( l = 0; l != maxLevels; ++l )
918 if( source && l == maxLevels-1 && source >= cellRow[ MOD_CELLSIZE( x ) ] )
919 randThreshold -= obj->mBalance[ *src ];
920 if( theError >= randThreshold + obj->mTreshHold[l] )
922 *raw |= ( maxLevels - l ) << rawShift;
923 theError -= obj->mWeight[l];
929 horBuf[3] += theError;
930 horBuf[1] += theError;
946 obj->mDo = LeftToRight16;
947 if( ++obj->mYInCell == CELLSIZE )
951void AOI_Screener::Internal::LeftToRight256( Internal* obj )
953 const uint8_t* src = obj->mParam.inputData;
954 uint8_t* raw = obj->mParam.rawBuffer;
955 int32_t bpp = obj->mParam.bytesPerPixel;
957 int maxLevels = obj->mLevels-1;
959 EDErr* horBuf = obj->mHorBuffer + 3;
960 EDErr theError = *horBuf;
961 uint16_t* cellRow = &obj->mCell[ MUL_CELLSIZE( obj->mYInCell ) ];
964 for( int32_t x = 0; x != obj->mWidth; ++x, src += bpp )
966 randThreshold = *obj->mThreshold;
967 if( obj->mThreshold == obj->mThresholdArray )
968 obj->mThreshold += 999;
972 source = obj->mParam.transferCurve[ *src ];
973 theError = EDErr( ( int32_t( theError ) + source ) >> 4 );
974 for( l = 0; l != maxLevels; ++l )
976 if( source && l == maxLevels-1 && source >= cellRow[ MOD_CELLSIZE( x ) ] )
977 randThreshold -= obj->mBalance[ *src ];
978 if( theError >= randThreshold + obj->mTreshHold[l] )
980 *raw = maxLevels - l;
981 theError -= obj->mWeight[l];
988 horBuf[-3] += theError;
989 horBuf[-1] += theError;
997 obj->mDo = RightToLeft256;
998 if( ++obj->mYInCell == CELLSIZE )
1002void AOI_Screener::Internal::RightToLeft256( Internal* obj )
1004 uint8_t* raw = obj->mParam.rawBuffer + obj->mRightOff;
1005 int32_t bpp = obj->mParam.bytesPerPixel;
1006 const uint8_t* src = obj->mParam.inputData + bpp * ( obj->mWidth - 1 );
1008 int maxLevels = obj->mLevels-1;
1010 EDErr* horBuf = obj->mHorBuffer + 3 + obj->mWidth - 1;
1011 EDErr theError = *horBuf;
1012 uint16_t* cellRow = &obj->mCell[ MUL_CELLSIZE( obj->mYInCell ) ];
1015 for( int32_t x = obj->mWidth - 1; x >= 0 ; --x, src -= bpp )
1017 randThreshold = *obj->mThreshold;
1018 if( obj->mThreshold == obj->mThresholdArray )
1019 obj->mThreshold += 999;
1023 source = obj->mParam.transferCurve[ *src ];
1024 theError = EDErr( ( int32_t( theError ) + source ) >> 4 );
1025 for( l = 0; l != maxLevels; ++l )
1027 if( source && l == maxLevels-1 && source >= cellRow[ MOD_CELLSIZE( x ) ] )
1028 randThreshold -= obj->mBalance[ *src ];
1029 if( theError >= randThreshold + obj->mTreshHold[l] )
1031 *raw = maxLevels - l;
1032 theError -= obj->mWeight[l];
1039 horBuf[3] += theError;
1040 horBuf[1] += theError;
1042 *horBuf += theError;
1045 theError += *horBuf;
1048 obj->mDo = LeftToRight256;
1049 if( ++obj->mYInCell == CELLSIZE )
1053void AOI_Screener::Internal::LeftToRight2_AntiClog( Internal* obj )
1055 const uint8_t* src = obj->mParam.inputData;
1056 uint8_t* raw = obj->mParam.rawBuffer;
1057 int32_t bpp = obj->mParam.bytesPerPixel;
1058 uint8_t rawMask = 0x80;
1059 EDErr* horBuf = obj->mHorBuffer + 3;
1060 EDErr theError = *horBuf;
1061 uint16_t* cellRow = &obj->mCell[ MUL_CELLSIZE( obj->mYInCell ) ];
1065 for( int32_t x = 0; x < obj->mWidth ; ++x, src += bpp )
1067 threshold = *obj->mThreshold + kTreshold;
1068 source = obj->mParam.transferCurve[ *src ];
1069 theError = EDErr( ( int32_t( theError ) + source ) >> 4 );
1070 if( source && source >= cellRow[ MOD_CELLSIZE( x ) ] )
1071 threshold -= obj->mBalance[ *src ];
1079 if( *raw == 0x54 || ( *raw != 0xA8 && theError >= threshold ) )
1082 theError -= kMaxPixelWeight;
1087 if( theError >= threshold )
1090 theError -= kMaxPixelWeight;
1094 if( obj->mThreshold == obj->mThresholdArray )
1095 obj->mThreshold += 999;
1099 if( ( rawMask >>= 1 ) == 0 )
1105 horBuf[-2] += ( theError << 1 ) + theError;
1106 horBuf[-1] += ( theError << 2 ) + theError;
1107 *horBuf += theError;
1109 theError = ( ( theError << 3 ) - theError ) + *horBuf;
1113 horBuf[-3] += theError;
1114 horBuf[-1] += theError;
1116 *horBuf += theError;
1119 theError += *horBuf;
1126 obj->mDo = RightToLeft2_AntiClog2;
1127 if( ++obj->mYInCell == CELLSIZE )
1131void AOI_Screener::Internal::RightToLeft2_AntiClog1( Internal* obj )
1133 uint8_t* raw = obj->mParam.rawBuffer + obj->mRightOff;
1134 int32_t bpp = obj->mParam.bytesPerPixel;
1135 const uint8_t* src = obj->mParam.inputData + bpp * ( obj->mWidth - 1 );
1136 EDErr* horBuf = obj->mHorBuffer + 3 + obj->mWidth - 1;
1137 EDErr theError = *horBuf;
1138 uint8_t rawMask = obj->mRightMask;
1139 uint16_t* cellRow = &obj->mCell[ MUL_CELLSIZE( obj->mYInCell ) ];
1143 for( int32_t x = obj->mWidth - 1; x >= 0 ; --x, src -= bpp )
1145 threshold = *obj->mThreshold + kTreshold;
1146 source = obj->mParam.transferCurve[ *src ];
1147 theError = EDErr( ( int32_t( theError ) + source ) >> 4 );
1148 if( source && source >= cellRow[ MOD_CELLSIZE( x ) ] )
1149 threshold -= obj->mBalance[ *src ];
1153 if( rawMask == 0x80 )
1157 if( *raw == 0x55 || ( *raw != 0x2A && theError >= threshold ) )
1160 theError -= kMaxPixelWeight;
1165 if( theError >= threshold )
1168 theError -= kMaxPixelWeight;
1172 if( obj->mThreshold == obj->mThresholdArray )
1173 obj->mThreshold += 999;
1177 if( ( rawMask <<= 1 ) == 0 )
1184 horBuf[2] += ( theError << 1 ) + theError;
1185 horBuf[1] += ( theError << 2 ) + theError;
1186 *horBuf += theError;
1188 theError = ( ( theError << 3 ) - theError ) + *horBuf;
1192 horBuf[3] += theError;
1193 horBuf[1] += theError;
1195 *horBuf += theError;
1198 theError += *horBuf;
1202 obj->mDo = LeftToRight2_AntiClog;
1203 if( ++obj->mYInCell == CELLSIZE )
1207void AOI_Screener::Internal::RightToLeft2_AntiClog2( Internal* obj )
1209 uint8_t* raw = obj->mParam.rawBuffer + obj->mRightOff;
1210 int32_t bpp = obj->mParam.bytesPerPixel;
1211 const uint8_t* src = obj->mParam.inputData + bpp * ( obj->mWidth - 1 );
1212 EDErr* horBuf = obj->mHorBuffer + 3 + obj->mWidth - 1;
1213 EDErr theError = *horBuf;
1214 uint8_t rawMask = obj->mRightMask;
1215 uint16_t* cellRow = &obj->mCell[ MUL_CELLSIZE( obj->mYInCell ) ];
1219 for( int32_t x = obj->mWidth - 1; x >= 0 ; --x, src -= bpp )
1221 threshold = *obj->mThreshold + kTreshold;
1222 source = obj->mParam.transferCurve[ *src ];
1223 theError = EDErr( ( int32_t( theError ) + source ) >> 4 );
1224 if( source && source >= cellRow[ MOD_CELLSIZE( x ) ] )
1225 threshold -= obj->mBalance[ *src ];
1229 if( rawMask == 0x80 )
1233 if( (*raw>>4) == 0x5 || ( (*raw>>4) != 0x2 && theError >= threshold ) )
1236 theError -= kMaxPixelWeight;
1239 else if( rawMask == 0x08 )
1243 if( *raw == 0x5 || ( *raw != 0x2 && theError >= threshold ) )
1246 theError -= kMaxPixelWeight;
1251 if( theError >= threshold )
1254 theError -= kMaxPixelWeight;
1258 if( obj->mThreshold == obj->mThresholdArray )
1259 obj->mThreshold += 999;
1263 if( ( rawMask <<= 1 ) == 0 )
1270 horBuf[2] += ( theError << 1 ) + theError;
1271 horBuf[1] += ( theError << 2 ) + theError;
1272 *horBuf += theError;
1274 theError = ( ( theError << 3 ) - theError ) + *horBuf;
1278 horBuf[3] += theError;
1279 horBuf[1] += theError;
1281 *horBuf += theError;
1284 theError += *horBuf;
1288 obj->mDo = LeftToRight2_AntiClog;
1289 if( ++obj->mYInCell == CELLSIZE )
1308 if( strstr( Instance::sLicenseOptions, OPT_SCREENING ) == NULL )
1309 throw ::ExceptionCode( 1 );
1313AOI_Screener::~AOI_Screener()
1336void AOI_Screener::PageStart( uint32_t channelCnt, uint32_t width, uint32_t , uint32_t levels,
const float* dotWeights,
const uint16_t* linCurve )
1338 Internal::Params params;
1339 params.bytesPerPixel = channelCnt;
1340 params.transferCurve = linCurve;
1341 params.maxPixelWidth = width;
1342 mInternal =
new Internal( params, NULL, 0, uint8_t( levels ), dotWeights + 1 );
1343 mInternal->StartPage( width );
1368 mInternal->Do( (
const uint8_t*)inLine, (uint8_t*)outLine );
void PageStart(uint32_t channelCnt, uint32_t width, uint32_t height, uint32_t levels, const float *dotWeights, const uint16_t *linCurve)
void ProcessLine(const void *inLine, void *outLine)
AOI_Screener(const char *screenerType)