/ software / apps / bad_apple / rle_decompress.S
rle_decompress.S
 1  // Note this is a fairly suboptimal approach now, see tmds_encode_1bpp in
 2  // tmds_encode.S for a faster and more general solution
 3  
 4  // Taking the encoder from DVI spec, with initial balance 0:
 5  // 
 6  // - Encoding either 0x00 or 0xff will produce a running balance of -8, with
 7  //   output symbol of 0x100 or 0x200
 8  // 
 9  // - Subsequently encoding either 0x01 or 0xfe will return the balance to 0, with
10  //  output symbol of 0x1ff or 0x2ff
11  // 
12  // So we can transform a black and white image to TMDS symbols with the
13  // following table:
14  // 
15  // x % 2 | Colour | Output
16  // ------+--------+--------
17  // 0     | 0      | 0x100
18  // 0     | 1      | 0x200
19  // 1     | 0      | 0x1ff
20  // 1     | 1      | 0x2ff
21  // 
22  // We will use this to unpack bytes encoded in the following RLE:
23  // 
24  // 7|6|5    0
25  // a|b|nnnnnn
26  // 
27  // where a, b are the colours of a two-pixel pair, and n is a repeat
28  // count between 1 and 64. 
29  
30  // r0: Input buffer (byte-aligned)
31  // r1: Output buffer (word-aligned)
32  // r2: Input size (bytes)
33  .global rle_to_tmds
34  .type rle_to_tmds,%function
35  .thumb_func
36  rle_to_tmds:
37  	push {r4, lr}
38  	add r2, r0
39  	mov ip, r2
40  	adr r4, tmds_table
41  	b 3f
42  1:
43  	ldrb r2, [r0]
44  	add r0, #1
45  
46  	// Load symbol pair
47  	lsr r3, r2, #6
48  	lsl r3, #2
49  	ldr r3, [r4, r3]
50  
51  	// run length - 1 in r2:
52  	lsl r2, #26
53  	lsr r2, #26
54  2:
55  	stmia r1!, {r3}
56  	sub r2, #1
57  	bcs 2b
58  3:
59  	cmp r0, ip
60  	bne 1b
61  	pop {r4, pc}
62  
63  .align 2
64  tmds_table:
65  	.word 0x7fd00 // 00
66  	.word 0xbfd00 // 10
67  	.word 0x7fe00 // 01
68  	.word 0xbfe00 // 11