@@ -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,7 +448,8 @@ 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 */
444
- && SDL_HasSSE42 () == SDL_TRUE
451
+ && byte_width == pitch &&
452
+ SDL_HasSSE42 () == SDL_TRUE
445
453
/* The SSE code assumes it will always read at least 4 pixels */
446
454
&& surf -> w >= 4
447
455
/* Our SSE code assumes masks are at most 0xff */
@@ -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
@@ -555,16 +564,28 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
555
564
return RAISE (PyExc_ValueError , "Unrecognized type of format" );
556
565
}
557
566
558
- bytes = PyBytes_FromStringAndSize (NULL , (Py_ssize_t )byte_width * surf -> h );
567
+ if (pitch == -1 ) {
568
+ pitch = byte_width ;
569
+ }
570
+ else if (pitch < byte_width ) {
571
+ return RAISE (PyExc_ValueError ,
572
+ "Pitch must be greater than or equal to the width "
573
+ "as per the format" );
574
+ }
575
+
576
+ bytes = PyBytes_FromStringAndSize (NULL , (Py_ssize_t )pitch * surf -> h );
559
577
if (!bytes )
560
578
return NULL ;
561
579
PyBytes_AsStringAndSize (bytes , & data , & len );
562
580
563
581
if (!strcmp (format , "P" )) {
564
582
pgSurface_Lock (surfobj );
565
- for (h = 0 ; h < surf -> h ; ++ h )
566
- memcpy (DATAROW (data , h , byte_width , surf -> h , flipped ),
567
- (char * )surf -> pixels + (h * surf -> pitch ), surf -> w );
583
+ for (h = 0 ; h < surf -> h ; ++ h ) {
584
+ Uint8 * ptr = (Uint8 * )DATAROW (data , h , pitch , surf -> h , flipped );
585
+ memcpy (ptr , (char * )surf -> pixels + (h * surf -> pitch ), surf -> w );
586
+ if (pitch > byte_width )
587
+ memset (ptr + byte_width , 0 , pitch - byte_width );
588
+ }
568
589
pgSurface_Unlock (surfobj );
569
590
}
570
591
else if (!strcmp (format , "RGB" )) {
@@ -582,6 +603,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
582
603
data [2 ] = (char )surf -> format -> palette -> colors [color ].b ;
583
604
data += 3 ;
584
605
}
606
+ PITCHPAD (data , byte_width , pitch )
585
607
}
586
608
break ;
587
609
case 2 :
@@ -595,6 +617,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
595
617
data [2 ] = (char )(((color & Bmask ) >> Bshift ) << Bloss );
596
618
data += 3 ;
597
619
}
620
+ PITCHPAD (data , byte_width , pitch )
598
621
}
599
622
break ;
600
623
case 3 :
@@ -613,6 +636,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
613
636
data [2 ] = (char )(((color & Bmask ) >> Bshift ) << Bloss );
614
637
data += 3 ;
615
638
}
639
+ PITCHPAD (data , byte_width , pitch )
616
640
}
617
641
break ;
618
642
case 4 :
@@ -626,6 +650,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
626
650
data [2 ] = (char )(((color & Bmask ) >> Bshift ) << Rloss );
627
651
data += 3 ;
628
652
}
653
+ PITCHPAD (data , byte_width , pitch )
629
654
}
630
655
break ;
631
656
}
@@ -648,6 +673,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
648
673
: (char )255 ;
649
674
data += 4 ;
650
675
}
676
+ PITCHPAD (data , byte_width , pitch )
651
677
}
652
678
break ;
653
679
case 2 :
@@ -667,6 +693,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
667
693
: 255 );
668
694
data += 4 ;
669
695
}
696
+ PITCHPAD (data , byte_width , pitch )
670
697
}
671
698
break ;
672
699
case 3 :
@@ -691,11 +718,12 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
691
718
: 255 );
692
719
data += 4 ;
693
720
}
721
+ PITCHPAD (data , byte_width , pitch )
694
722
}
695
723
break ;
696
724
case 4 :
697
725
tobytes_surf_32bpp (surf , flipped , hascolorkey , colorkey , data ,
698
- 0 , 3 );
726
+ 0 , 3 , pitch );
699
727
break ;
700
728
}
701
729
pgSurface_Unlock (surfobj );
@@ -715,6 +743,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
715
743
data [0 ] = (char )255 ;
716
744
data += 4 ;
717
745
}
746
+ PITCHPAD (data , byte_width , pitch )
718
747
}
719
748
break ;
720
749
case 2 :
@@ -731,6 +760,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
731
760
: 255 );
732
761
data += 4 ;
733
762
}
763
+ PITCHPAD (data , byte_width , pitch )
734
764
}
735
765
break ;
736
766
case 3 :
@@ -752,11 +782,12 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
752
782
: 255 );
753
783
data += 4 ;
754
784
}
785
+ PITCHPAD (data , byte_width , pitch )
755
786
}
756
787
break ;
757
788
case 4 :
758
789
tobytes_surf_32bpp (surf , flipped , hascolorkey , colorkey , data ,
759
- 1 , 0 );
790
+ 1 , 0 , pitch );
760
791
break ;
761
792
}
762
793
pgSurface_Unlock (surfobj );
@@ -776,6 +807,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
776
807
data [3 ] = (char )255 ;
777
808
data += 4 ;
778
809
}
810
+ PITCHPAD (data , byte_width , pitch )
779
811
}
780
812
break ;
781
813
case 2 :
@@ -792,6 +824,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
792
824
: 255 );
793
825
data += 4 ;
794
826
}
827
+ PITCHPAD (data , byte_width , pitch )
795
828
}
796
829
break ;
797
830
case 3 :
@@ -813,6 +846,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
813
846
: 255 );
814
847
data += 4 ;
815
848
}
849
+ PITCHPAD (data , byte_width , pitch )
816
850
}
817
851
break ;
818
852
case 4 :
@@ -829,6 +863,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
829
863
: 255 );
830
864
data += 4 ;
831
865
}
866
+ PITCHPAD (data , byte_width , pitch )
832
867
}
833
868
break ;
834
869
}
@@ -856,6 +891,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
856
891
data [3 ] = (char )alpha ;
857
892
data += 4 ;
858
893
}
894
+ PITCHPAD (data , byte_width , pitch )
859
895
}
860
896
break ;
861
897
case 3 :
@@ -882,6 +918,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
882
918
data [3 ] = (char )alpha ;
883
919
data += 4 ;
884
920
}
921
+ PITCHPAD (data , byte_width , pitch )
885
922
}
886
923
break ;
887
924
case 4 :
@@ -908,6 +945,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
908
945
data [3 ] = (char )alpha ;
909
946
data += 4 ;
910
947
}
948
+ PITCHPAD (data , byte_width , pitch )
911
949
}
912
950
break ;
913
951
}
@@ -935,6 +973,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
935
973
data [0 ] = (char )alpha ;
936
974
data += 4 ;
937
975
}
976
+ PITCHPAD (data , byte_width , pitch )
938
977
}
939
978
break ;
940
979
case 3 :
@@ -961,6 +1000,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
961
1000
data [0 ] = (char )alpha ;
962
1001
data += 4 ;
963
1002
}
1003
+ PITCHPAD (data , byte_width , pitch )
964
1004
}
965
1005
break ;
966
1006
case 4 :
@@ -987,6 +1027,7 @@ image_tobytes(PyObject *self, PyObject *arg, PyObject *kwarg)
987
1027
data [0 ] = (char )alpha ;
988
1028
data += 4 ;
989
1029
}
1030
+ PITCHPAD (data , byte_width , pitch )
990
1031
}
991
1032
break ;
992
1033
}
0 commit comments