@@ -45,6 +45,12 @@ SaveTGA_RW(SDL_Surface *surface, SDL_RWops *out, int rle);
45
45
((flipped) ? (((char *)data) + (height - row - 1) * width) \
46
46
: (((char *)data) + row * width))
47
47
48
+ #define PITCHPAD (data , byte_width , pitch ) \
49
+ if (pitch > byte_width) { \
50
+ memset(data, 0, pitch - byte_width); \
51
+ data += pitch - byte_width; \
52
+ }
53
+
48
54
static PyObject * extloadobj = NULL ;
49
55
static PyObject * extsaveobj = NULL ;
50
56
static PyObject * extverobj = NULL ;
@@ -414,9 +420,10 @@ tobytes_surf_32bpp_sse42(SDL_Surface *surf, int flipped, char *data,
414
420
static void
415
421
tobytes_surf_32bpp (SDL_Surface * surf , int flipped , int hascolorkey ,
416
422
Uint32 colorkey , char * serialized_image , int color_offset ,
417
- int alpha_offset )
423
+ int alpha_offset , int pitch )
418
424
{
419
425
int w , h ;
426
+ int byte_width = surf -> w * 4 ;
420
427
421
428
Uint32 Rmask = surf -> format -> Rmask ;
422
429
Uint32 Gmask = surf -> format -> Gmask ;
@@ -441,6 +448,7 @@ tobytes_surf_32bpp(SDL_Surface *surf, int flipped, int hascolorkey,
441
448
sizeof (int ) == sizeof (Uint32 ) &&
442
449
4 * sizeof (Uint32 ) == sizeof (__m128i ) &&
443
450
!hascolorkey /* No color key */
451
+ && byte_width == pitch
444
452
&& SDL_HasSSE42 () == SDL_TRUE
445
453
/* The SSE code assumes it will always read at least 4 pixels */
446
454
&& surf -> w >= 4
@@ -480,6 +488,7 @@ tobytes_surf_32bpp(SDL_Surface *surf, int flipped, int hascolorkey,
480
488
: 255 );
481
489
serialized_image += 4 ;
482
490
}
491
+ PITCHPAD (serialized_image , byte_width , pitch )
483
492
}
484
493
}
485
494
@@ -490,25 +499,25 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
490
499
PyObject * bytes = NULL ;
491
500
char * format , * data ;
492
501
SDL_Surface * surf ;
493
- int w , h , flipped = 0 ;
502
+ int w , h , flipped = 0 , pitch = -1 ;
494
503
int byte_width ;
495
504
Py_ssize_t len ;
496
505
Uint32 Rmask , Gmask , Bmask , Amask , Rshift , Gshift , Bshift , Ashift , Rloss ,
497
506
Gloss , Bloss , Aloss ;
498
507
int hascolorkey = 0 ;
499
508
Uint32 color , colorkey ;
500
509
Uint32 alpha ;
501
- static char * kwds [] = {"surface" , "format" , "flipped" , NULL };
510
+ static char * kwds [] = {"surface" , "format" , "flipped" , "pitch" , NULL };
502
511
503
512
#ifdef _MSC_VER
504
513
/* MSVC static analyzer false alarm: assure format is NULL-terminated by
505
514
* making analyzer assume it was initialised */
506
515
__analysis_assume (format = "inited" );
507
516
#endif
508
517
509
- if (!PyArg_ParseTupleAndKeywords (arg , kwarg , "O!s|i " , kwds ,
518
+ if (!PyArg_ParseTupleAndKeywords (arg , kwarg , "O!s|ii " , kwds ,
510
519
& pgSurface_Type , & surfobj , & format ,
511
- & flipped ))
520
+ & flipped , & pitch ))
512
521
return NULL ;
513
522
surf = pgSurface_AsSurface (surfobj );
514
523
@@ -556,16 +565,28 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
556
565
return RAISE (PyExc_ValueError , "Unrecognized type of format" );
557
566
}
558
567
559
- bytes = PyBytes_FromStringAndSize (NULL , (Py_ssize_t )byte_width * surf -> h );
568
+ if (pitch == -1 ) {
569
+ pitch = byte_width ;
570
+ }
571
+ else if (pitch < byte_width ) {
572
+ return RAISE (PyExc_ValueError ,
573
+ "Pitch must be greater than or equal to the width "
574
+ "as per the format" );
575
+ }
576
+
577
+ bytes = PyBytes_FromStringAndSize (NULL , (Py_ssize_t )pitch * surf -> h );
560
578
if (!bytes )
561
579
return NULL ;
562
580
PyBytes_AsStringAndSize (bytes , & data , & len );
563
581
564
582
if (!strcmp (format , "P" )) {
565
583
pgSurface_Lock (surfobj );
566
- for (h = 0 ; h < surf -> h ; ++ h )
567
- memcpy (DATAROW (data , h , byte_width , surf -> h , flipped ),
568
- (char * )surf -> pixels + (h * surf -> pitch ), surf -> w );
584
+ for (h = 0 ; h < surf -> h ; ++ h ) {
585
+ Uint8 * ptr = (Uint8 * )DATAROW (data , h , pitch , surf -> h , flipped );
586
+ memcpy (ptr , (char * )surf -> pixels + (h * surf -> pitch ), surf -> w );
587
+ if (pitch > byte_width )
588
+ memset (ptr + byte_width , 0 , pitch - byte_width );
589
+ }
569
590
pgSurface_Unlock (surfobj );
570
591
}
571
592
else if (!strcmp (format , "RGB" )) {
@@ -583,6 +604,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
583
604
data [2 ] = (char )surf -> format -> palette -> colors [color ].b ;
584
605
data += 3 ;
585
606
}
607
+ PITCHPAD (data , byte_width , pitch )
586
608
}
587
609
break ;
588
610
case 2 :
@@ -596,6 +618,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
596
618
data [2 ] = (char )(((color & Bmask ) >> Bshift ) << Bloss );
597
619
data += 3 ;
598
620
}
621
+ PITCHPAD (data , byte_width , pitch )
599
622
}
600
623
break ;
601
624
case 3 :
@@ -614,6 +637,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
614
637
data [2 ] = (char )(((color & Bmask ) >> Bshift ) << Bloss );
615
638
data += 3 ;
616
639
}
640
+ PITCHPAD (data , byte_width , pitch )
617
641
}
618
642
break ;
619
643
case 4 :
@@ -627,6 +651,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
627
651
data [2 ] = (char )(((color & Bmask ) >> Bshift ) << Rloss );
628
652
data += 3 ;
629
653
}
654
+ PITCHPAD (data , byte_width , pitch )
630
655
}
631
656
break ;
632
657
}
@@ -649,6 +674,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
649
674
: (char )255 ;
650
675
data += 4 ;
651
676
}
677
+ PITCHPAD (data , byte_width , pitch )
652
678
}
653
679
break ;
654
680
case 2 :
@@ -668,6 +694,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
668
694
: 255 );
669
695
data += 4 ;
670
696
}
697
+ PITCHPAD (data , byte_width , pitch )
671
698
}
672
699
break ;
673
700
case 3 :
@@ -692,11 +719,12 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
692
719
: 255 );
693
720
data += 4 ;
694
721
}
722
+ PITCHPAD (data , byte_width , pitch )
695
723
}
696
724
break ;
697
725
case 4 :
698
726
tobytes_surf_32bpp (surf , flipped , hascolorkey , colorkey , data ,
699
- 0 , 3 );
727
+ 0 , 3 , pitch );
700
728
break ;
701
729
}
702
730
pgSurface_Unlock (surfobj );
@@ -716,6 +744,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
716
744
data [0 ] = (char )255 ;
717
745
data += 4 ;
718
746
}
747
+ PITCHPAD (data , byte_width , pitch )
719
748
}
720
749
break ;
721
750
case 2 :
@@ -732,6 +761,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
732
761
: 255 );
733
762
data += 4 ;
734
763
}
764
+ PITCHPAD (data , byte_width , pitch )
735
765
}
736
766
break ;
737
767
case 3 :
@@ -753,11 +783,12 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
753
783
: 255 );
754
784
data += 4 ;
755
785
}
786
+ PITCHPAD (data , byte_width , pitch )
756
787
}
757
788
break ;
758
789
case 4 :
759
790
tobytes_surf_32bpp (surf , flipped , hascolorkey , colorkey , data ,
760
- 1 , 0 );
791
+ 1 , 0 , pitch );
761
792
break ;
762
793
}
763
794
pgSurface_Unlock (surfobj );
@@ -777,6 +808,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
777
808
data [3 ] = (char )255 ;
778
809
data += 4 ;
779
810
}
811
+ PITCHPAD (data , byte_width , pitch )
780
812
}
781
813
break ;
782
814
case 2 :
@@ -793,6 +825,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
793
825
: 255 );
794
826
data += 4 ;
795
827
}
828
+ PITCHPAD (data , byte_width , pitch )
796
829
}
797
830
break ;
798
831
case 3 :
@@ -814,6 +847,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
814
847
: 255 );
815
848
data += 4 ;
816
849
}
850
+ PITCHPAD (data , byte_width , pitch )
817
851
}
818
852
break ;
819
853
case 4 :
@@ -830,6 +864,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
830
864
: 255 );
831
865
data += 4 ;
832
866
}
867
+ PITCHPAD (data , byte_width , pitch )
833
868
}
834
869
break ;
835
870
}
@@ -857,6 +892,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
857
892
data [3 ] = (char )alpha ;
858
893
data += 4 ;
859
894
}
895
+ PITCHPAD (data , byte_width , pitch )
860
896
}
861
897
break ;
862
898
case 3 :
@@ -883,6 +919,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
883
919
data [3 ] = (char )alpha ;
884
920
data += 4 ;
885
921
}
922
+ PITCHPAD (data , byte_width , pitch )
886
923
}
887
924
break ;
888
925
case 4 :
@@ -909,6 +946,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
909
946
data [3 ] = (char )alpha ;
910
947
data += 4 ;
911
948
}
949
+ PITCHPAD (data , byte_width , pitch )
912
950
}
913
951
break ;
914
952
}
@@ -936,6 +974,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
936
974
data [0 ] = (char )alpha ;
937
975
data += 4 ;
938
976
}
977
+ PITCHPAD (data , byte_width , pitch )
939
978
}
940
979
break ;
941
980
case 3 :
@@ -962,6 +1001,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
962
1001
data [0 ] = (char )alpha ;
963
1002
data += 4 ;
964
1003
}
1004
+ PITCHPAD (data , byte_width , pitch )
965
1005
}
966
1006
break ;
967
1007
case 4 :
@@ -988,6 +1028,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
988
1028
data [0 ] = (char )alpha ;
989
1029
data += 4 ;
990
1030
}
1031
+ PITCHPAD (data , byte_width , pitch )
991
1032
}
992
1033
break ;
993
1034
}
0 commit comments