@@ -57,6 +57,19 @@ const RAW_RGB_2X2 = Buffer.from([
5757 255 , 0 , 0 , 0 , 255 , 0 ,
5858 0 , 0 , 255 , 255 , 255 , 0
5959] ) . toString ( 'base64' ) ;
60+ // 5 pixels (1 uint32 block + 1 remainder) — tests block+tail boundary
61+ const RAW_RGB_5X1 = Buffer . from ( [
62+ 255 , 0 , 0 ,
63+ 0 , 255 , 0 ,
64+ 0 , 0 , 255 ,
65+ 255 , 255 , 0 ,
66+ 255 , 0 , 255
67+ ] ) . toString ( 'base64' ) ;
68+ // 8 pixels (2 full uint32 blocks, 0 remainder) — tests multi-block path
69+ const RAW_RGB_4X2 = Buffer . from ( [
70+ 255 , 0 , 0 , 0 , 255 , 0 , 0 , 0 , 255 , 255 , 255 , 0 ,
71+ 255 , 0 , 255 , 0 , 255 , 255 , 128 , 128 , 128 , 255 , 255 , 255
72+ ] ) . toString ( 'base64' ) ;
6073
6174// Raw RGBA pixel data (f=32): 4 bytes per pixel, no header — requires s= and v=
6275const RAW_RGBA_1X1_WHITE = Buffer . from ( [ 255 , 255 , 255 , 255 ] ) . toString ( 'base64' ) ;
@@ -71,6 +84,14 @@ const RAW_RGBA_2X2 = Buffer.from([
7184 255 , 0 , 0 , 255 , 0 , 255 , 0 , 255 ,
7285 0 , 0 , 255 , 255 , 255 , 255 , 0 , 255
7386] ) . toString ( 'base64' ) ;
87+ // 5 pixels — tests RGBA zero-copy with non-power-of-2 count
88+ const RAW_RGBA_5X1 = Buffer . from ( [
89+ 255 , 0 , 0 , 255 ,
90+ 0 , 255 , 0 , 255 ,
91+ 0 , 0 , 255 , 255 ,
92+ 255 , 255 , 0 , 255 ,
93+ 255 , 0 , 255 , 255
94+ ] ) . toString ( 'base64' ) ;
7495
7596let ctx : ITestContext ;
7697test . beforeAll ( async ( { browser } ) => {
@@ -1449,6 +1470,29 @@ test.describe('Kitty Graphics Protocol', () => {
14491470 deepStrictEqual ( await getPixel ( 0 , 0 , 0 , 1 ) , [ 0 , 0 , 255 , 255 ] ) ;
14501471 deepStrictEqual ( await getPixel ( 0 , 0 , 1 , 1 ) , [ 255 , 255 , 0 , 255 ] ) ;
14511472 } ) ;
1473+
1474+ test ( 'renders 5x1 row with block+remainder pixel layout' , async ( ) => {
1475+ await ctx . proxy . write ( `\x1b_Ga=T,f=24,s=5,v=1;${ RAW_RGB_5X1 } \x1b\\` ) ;
1476+ await timeout ( 100 ) ;
1477+ deepStrictEqual ( await getPixel ( 0 , 0 , 0 , 0 ) , [ 255 , 0 , 0 , 255 ] ) ;
1478+ deepStrictEqual ( await getPixel ( 0 , 0 , 1 , 0 ) , [ 0 , 255 , 0 , 255 ] ) ;
1479+ deepStrictEqual ( await getPixel ( 0 , 0 , 2 , 0 ) , [ 0 , 0 , 255 , 255 ] ) ;
1480+ deepStrictEqual ( await getPixel ( 0 , 0 , 3 , 0 ) , [ 255 , 255 , 0 , 255 ] ) ;
1481+ deepStrictEqual ( await getPixel ( 0 , 0 , 4 , 0 ) , [ 255 , 0 , 255 , 255 ] ) ;
1482+ } ) ;
1483+
1484+ test ( 'renders 4x2 grid with multi-block pixel layout' , async ( ) => {
1485+ await ctx . proxy . write ( `\x1b_Ga=T,f=24,s=4,v=2;${ RAW_RGB_4X2 } \x1b\\` ) ;
1486+ await timeout ( 100 ) ;
1487+ deepStrictEqual ( await getPixel ( 0 , 0 , 0 , 0 ) , [ 255 , 0 , 0 , 255 ] ) ;
1488+ deepStrictEqual ( await getPixel ( 0 , 0 , 1 , 0 ) , [ 0 , 255 , 0 , 255 ] ) ;
1489+ deepStrictEqual ( await getPixel ( 0 , 0 , 2 , 0 ) , [ 0 , 0 , 255 , 255 ] ) ;
1490+ deepStrictEqual ( await getPixel ( 0 , 0 , 3 , 0 ) , [ 255 , 255 , 0 , 255 ] ) ;
1491+ deepStrictEqual ( await getPixel ( 0 , 0 , 0 , 1 ) , [ 255 , 0 , 255 , 255 ] ) ;
1492+ deepStrictEqual ( await getPixel ( 0 , 0 , 1 , 1 ) , [ 0 , 255 , 255 , 255 ] ) ;
1493+ deepStrictEqual ( await getPixel ( 0 , 0 , 2 , 1 ) , [ 128 , 128 , 128 , 255 ] ) ;
1494+ deepStrictEqual ( await getPixel ( 0 , 0 , 3 , 1 ) , [ 255 , 255 , 255 , 255 ] ) ;
1495+ } ) ;
14521496 } ) ;
14531497
14541498 test . describe ( 'Storage and dimensions' , ( ) => {
@@ -1465,6 +1509,20 @@ test.describe('Kitty Graphics Protocol', () => {
14651509 strictEqual ( await getImageStorageLength ( ) , 1 ) ;
14661510 deepStrictEqual ( await getOrigSize ( 1 ) , [ 2 , 2 ] ) ;
14671511 } ) ;
1512+
1513+ test ( 'stores image with correct original dimensions (5x1)' , async ( ) => {
1514+ await ctx . proxy . write ( `\x1b_Ga=T,f=24,s=5,v=1;${ RAW_RGB_5X1 } \x1b\\` ) ;
1515+ await timeout ( 100 ) ;
1516+ strictEqual ( await getImageStorageLength ( ) , 1 ) ;
1517+ deepStrictEqual ( await getOrigSize ( 1 ) , [ 5 , 1 ] ) ;
1518+ } ) ;
1519+
1520+ test ( 'stores image with correct original dimensions (4x2)' , async ( ) => {
1521+ await ctx . proxy . write ( `\x1b_Ga=T,f=24,s=4,v=2;${ RAW_RGB_4X2 } \x1b\\` ) ;
1522+ await timeout ( 100 ) ;
1523+ strictEqual ( await getImageStorageLength ( ) , 1 ) ;
1524+ deepStrictEqual ( await getOrigSize ( 1 ) , [ 4 , 2 ] ) ;
1525+ } ) ;
14681526 } ) ;
14691527
14701528 test . describe ( 'Validation' , ( ) => {
@@ -1566,6 +1624,16 @@ test.describe('Kitty Graphics Protocol', () => {
15661624 deepStrictEqual ( await getPixel ( 0 , 0 , 0 , 1 ) , [ 0 , 0 , 255 , 255 ] ) ;
15671625 deepStrictEqual ( await getPixel ( 0 , 0 , 1 , 1 ) , [ 255 , 255 , 0 , 255 ] ) ;
15681626 } ) ;
1627+
1628+ test ( 'renders 5x1 row with zero-copy pixel layout' , async ( ) => {
1629+ await ctx . proxy . write ( `\x1b_Ga=T,f=32,s=5,v=1;${ RAW_RGBA_5X1 } \x1b\\` ) ;
1630+ await timeout ( 100 ) ;
1631+ deepStrictEqual ( await getPixel ( 0 , 0 , 0 , 0 ) , [ 255 , 0 , 0 , 255 ] ) ;
1632+ deepStrictEqual ( await getPixel ( 0 , 0 , 1 , 0 ) , [ 0 , 255 , 0 , 255 ] ) ;
1633+ deepStrictEqual ( await getPixel ( 0 , 0 , 2 , 0 ) , [ 0 , 0 , 255 , 255 ] ) ;
1634+ deepStrictEqual ( await getPixel ( 0 , 0 , 3 , 0 ) , [ 255 , 255 , 0 , 255 ] ) ;
1635+ deepStrictEqual ( await getPixel ( 0 , 0 , 4 , 0 ) , [ 255 , 0 , 255 , 255 ] ) ;
1636+ } ) ;
15691637 } ) ;
15701638
15711639 test . describe ( 'Storage and dimensions' , ( ) => {
@@ -1582,6 +1650,13 @@ test.describe('Kitty Graphics Protocol', () => {
15821650 strictEqual ( await getImageStorageLength ( ) , 1 ) ;
15831651 deepStrictEqual ( await getOrigSize ( 1 ) , [ 2 , 2 ] ) ;
15841652 } ) ;
1653+
1654+ test ( 'stores image with correct original dimensions (5x1)' , async ( ) => {
1655+ await ctx . proxy . write ( `\x1b_Ga=T,f=32,s=5,v=1;${ RAW_RGBA_5X1 } \x1b\\` ) ;
1656+ await timeout ( 100 ) ;
1657+ strictEqual ( await getImageStorageLength ( ) , 1 ) ;
1658+ deepStrictEqual ( await getOrigSize ( 1 ) , [ 5 , 1 ] ) ;
1659+ } ) ;
15851660 } ) ;
15861661
15871662 test . describe ( 'Validation' , ( ) => {
0 commit comments