@@ -422,17 +422,24 @@ SaneDev_snap(SaneDevObject *self, PyObject *args)
422422
423423 RAISE_IF (p .depth != 1 && p .depth != 8 && p .depth != 16 , "Bad pixel depth" );
424424
425- int imgSampelsPerPixel = (p .format == SANE_FRAME_GRAY ? 1 : 3 );
425+ int imgSamplesPerPixel = (p .format == SANE_FRAME_GRAY ? 1 : 3 );
426426 int imgPixelsPerLine = p .pixels_per_line ;
427427 int imgSampleSize = (p .depth == 16 && allow16bitsamples ? 2 : 1 );
428- int imgBytesPerLine = imgPixelsPerLine * imgSampelsPerPixel * imgSampleSize ;
428+ int imgBytesPerLine = imgPixelsPerLine * imgSamplesPerPixel * imgSampleSize ;
429+ int imgBytesPerScanLine = imgBytesPerLine ;
430+ if (p .depth == 1 )
431+ {
432+ /* See Sane spec chapter 4.3.8 */
433+ imgBytesPerScanLine = imgSamplesPerPixel * ((imgPixelsPerLine + 7 ) / 8 );
434+ }
429435 int imgBufCurLine = 0 ;
430436 int imgBufLines = p .lines < 1 ? 1 : p .lines ;
437+ const unsigned char bitMasks [8 ] = {128 , 64 , 32 , 16 , 8 , 4 , 2 , 1 };
431438 SANE_Byte * imgBuf = (SANE_Byte * )malloc (imgBufLines * imgBytesPerLine );
432439
433440 SANE_Int lineBufUsed = 0 ;
434- SANE_Byte * lineBuf = (SANE_Byte * )malloc (imgBytesPerLine );
435- int i ;
441+ SANE_Byte * lineBuf = (SANE_Byte * )malloc (imgBytesPerScanLine );
442+ int i , j ;
436443
437444 /* Read data */
438445 Py_BEGIN_ALLOW_THREADS
@@ -442,11 +449,11 @@ SaneDev_snap(SaneDevObject *self, PyObject *args)
442449 {
443450 /* Read one line */
444451 lineBufUsed = 0 ;
445- while (lineBufUsed < imgBytesPerLine )
452+ while (lineBufUsed < imgBytesPerScanLine )
446453 {
447454 SANE_Int nRead = 0 ;
448455 st = sane_read (self -> h , lineBuf + lineBufUsed ,
449- imgBytesPerLine - lineBufUsed ,
456+ imgBytesPerScanLine - lineBufUsed ,
450457 & nRead );
451458 if (st != SANE_STATUS_GOOD )
452459 break ;
@@ -484,8 +491,16 @@ SaneDev_snap(SaneDevObject *self, PyObject *args)
484491 {
485492 if (p .depth == 1 )
486493 {
487- for (i = 0 ; i < imgBytesPerLine ; ++ i )
488- imgBuf [imgBufOffset + i ] = lineBuf [i / 8 ] & (0x80 >> (i % 8 )) ? 0 : 255 ;
494+ /* See Sane spec chapter 3.2.1 */
495+ for (j = 0 ; j < imgSamplesPerPixel ; ++ j )
496+ {
497+ for (i = 0 ; i < imgPixelsPerLine ; ++ i )
498+ {
499+ int iImgBuf = imgBufOffset + imgSamplesPerPixel * i + j ;
500+ int lineByte = imgSamplesPerPixel * (i / 8 ) + j ;
501+ imgBuf [iImgBuf ] = (lineBuf [lineByte ] & bitMasks [i % 8 ]) ? 0 : 255 ;
502+ }
503+ }
489504 }
490505 else if (p .depth == 8 )
491506 {
@@ -511,8 +526,12 @@ SaneDev_snap(SaneDevObject *self, PyObject *args)
511526 int channel = p .format - SANE_FRAME_RED ;
512527 if (p .depth == 1 )
513528 {
514- for (i = 0 ; i < p .pixels_per_line ; ++ i )
515- imgBuf [imgBufOffset + 3 * i + channel ] = lineBuf [i / 8 ] & (0x80 >> (i % 8 )) ? 0 : 255 ;
529+ /* See Sane spec chapter 3.2.1 */
530+ for (i = 0 ; i < imgPixelsPerLine ; ++ i )
531+ {
532+ int iImgBuf = imgBufOffset + 3 * i + channel ;
533+ imgBuf [iImgBuf ] = (lineBuf [i / 8 ] & bitMasks [i % 8 ]) ? 0 : 255 ;
534+ }
516535 }
517536 else if (p .depth == 8 )
518537 {
@@ -569,7 +588,7 @@ SaneDev_snap(SaneDevObject *self, PyObject *args)
569588 return NULL ;
570589
571590 PyObject * ret = Py_BuildValue ("Oiiii" , pyByteArray , imgPixelsPerLine ,
572- imgBufLines , imgSampelsPerPixel ,
591+ imgBufLines , imgSamplesPerPixel ,
573592 imgSampleSize );
574593 Py_DECREF (pyByteArray );
575594
0 commit comments