`Page 1/10
`Saved: 9/6/01, 4:07:58 PM
`Printed for: Implicit
`
`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`1
`+++++¬
`…
`¬2
`Copyright (c) 2001 BeComm Corporation¬
`3
`¬4
`Filename:¬
`5
`¬6
` bmpdecoder.c¬
`7
`¬8
`Group Name:¬
`9
`¬10
` todo¬
`11
`¬12
`Group Overview:¬
`13
`¬14
` todo¬
`15
`¬16
`Owner:¬
`17
`¬18
` Guy Carpenter (guyc) 19-Jul-2001¬
`19
`¬20
`--------------------------------------------------------------------------
`21
`---*/¬
`…
`¬22
`#define SOS_DEBUG_ZONE "/beads/bmpdisplay"¬
`23
`¬24
`#include <sosstrings.h>¬
`25
`#include "bmpdecoder.h"¬
`26
`¬27
`SOS_SOURCE_VERSION (¬
`28
` "$Id: bmpdecoder.c,v 1.1 2001/09/06 21:07:58 guyc Exp $"¬
`29
`);¬
`30
`¬31
`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`32
`+++++¬
`…
`Types and Structures¬
`33
`++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`34
`+++*/¬
`…
`¬35
`¬36
`¬37
`struct _BMP_DECODER {¬
`38
` BMP_FORMAT
`39
` SOS_UINT32 *
`40
` SOS_BOOLEAN
`41
`
`Format;¬
`ColorInfo;¬
`FormatIsSet;¬
`
`Page 1 of 10
`
`Implicit Exhibit 2044
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/bmpdecoder.c
`Page 2/10
`Saved: 9/6/01, 4:07:58 PM
`Printed for: Implicit
`
`};¬
`42
`¬43
`/* is this word or dword alignment?¬
`44
` * V1 used dword, so we will too¬
`45
` */¬
`46
`#define WORD_ALIGN(X) ((X+1)&(SOS_UINT32_MAX-1))¬
`47
`#define DWORD_ALIGN(X) ((X+3)&(SOS_UINT32_MAX-3))¬
`48
`#define RLE8_WRITE_PIXEL(P) *dest++=BmpDecoder->ColorInfo[P]¬
`49
`¬50
`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`51
`+++++¬
`…
`Decoders¬
`52
`++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`53
`+++*/¬
`…
`static¬
`54
`SOS_STATUS¬
`55
`FrameDecode_Rle8(¬
`56
` BMP_DECODER * BmpDecoder,¬
`57
` void * EncodedFrame,¬
`58
` size_t EncodedFrameSize,¬
`59
` void * DecodedFrame,¬
`60
` size_t DecodedFrameSize¬
`61
`)¬
`62
`{¬
`63
` SOS_STATUS status = SOS_Success;¬
`64
` unsigned char *src = EncodedFrame;¬
`65
` SOS_UINT32 size = EncodedFrameSize;¬
`66
` SOS_UINT32 align;¬
`67
` unsigned char count;¬
`68
` SOS_UINT32 width = BmpDecoder->Format.Width;¬
`69
` SOS_UINT32 height= BmpDecoder->Format.Height;¬
`70
` SOS_UINT32 *dest = DecodedFrame;¬
`71
`¬72
` /* destEnd is the pixel entry following¬
`73
` the legal write area, used to detect overflow */¬
`74
` SOS_UINT32 *destEnd = dest+(DecodedFrameSize/sizeof(SOS_UINT32));¬
`75
` dest += width * (height-1);¬
`76
`¬77
` /*¬
`78
` * In debug mode we check the cursor position to make sure it never¬
`79
` * gets out of bounds.¬
`80
` */¬
`81
`#if DEBUG¬
`82
`#define CHECK() if (dest<(SOS_UINT32*)DecodedFrame || dest>=destEnd)
`83
`{SOS_Debug_StringPrint("Range check failed %p %p
`…
`
`Page 2 of 10
`
`Implicit Exhibit 2044
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/bmpdecoder.c
`Page 3/10
`Saved: 9/6/01, 4:07:58 PM
`Printed for: Implicit
`
`%p\n",DecodedFrame,dest,destEnd);SOS_ASSERT_ASSUMPTION(0,"check");}¬
`83…
`#else¬
`84
`#define CHECK()¬
`85
`#endif¬
`86
` ¬
`87
` /*¬
`88
` * This loop is written with the intention of making easy¬
`89
` * to support streaming (incremental processing as data¬
`90
` * becomes available). At this stage it isn't needed.¬
`91
` */¬
`92
`¬93
`// SOS_DEBUG_LEVEL_SET(5);¬
`94
` ¬
`95
` while (size>=2) { /* need two bytes minimum for any op */¬
`96
` if (src[0]==0) {¬
`97
` /*¬
`98
` * PROCESS ESCAPES¬
`99
` * 0 character is an escape. Meaning¬
`100
` * depends upon following character:¬
`101
` * 0: end of line¬
`102
` * 1: end of bitmap¬
`103
` * 2: delta - following two bytes contain unsigned values
`104
`indicating¬
`…
` * the horizontal and vertical offsets of the next pixel.¬
`105
` * default: next byte represents number of following bytes¬
`106
` * each of which contains the index of a single pixel.
`107
`When¬
`…
` * second byte is 2 or less, has same meaning as in encoded¬
`108
` * mode. In absolute mode, each run must end on 2-byte¬
`109
` * word boundary.¬
`110
` */¬
`111
` switch (src[1]) {¬
`112
` case 0: /* end of line */¬
`113
` {¬
`114
` SOS_UINT32 *start = (SOS_UINT32*)DecodedFrame;¬
`115
` size_t delta = dest - start;¬
`116
` size_t x = delta % width;¬
`117
` size_t y = delta / width;¬
`118
` SOS_DEBUGOUT_FUNC_TRACE(¬
`119
` "BMP escape eol %ld %ld\n",¬
`120
` x,y¬
`121
` );¬
`122
` }¬
`123
` src+=2; /* consume two bytes */¬
`124
` size-=2;¬
`125
`
`Page 3 of 10
`
`Implicit Exhibit 2044
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/bmpdecoder.c
`Page 4/10
`Saved: 9/6/01, 4:07:58 PM
`Printed for: Implicit
`
`126
`127
`128
`129
`130
`131
`132
`133
`…
`134
`135
`136
`137
`138
`139
`140
`141
`142
`143
`144
`145
`146
`147
`148
`149
`150
`151
`152
`153
`154
`155
`156
`157
`158
`159
`160
`161
`162
`163
`164
`165
`166
`167
`168
`169
`
` /* step to start of next line¬
` * need to be careful here. If we just¬
` * stepped over the end of the line, we dont¬
` * want to skip again. We assume there¬
` * wont be a eol at position 0¬
` */¬
` {¬
`// size_t y = ((dest-1-(SOS_UINT32*)DecodedFrame) %
`width);¬
`// dest += width - y - 1;¬
`¬
` size_t x = ((dest-(SOS_UINT32*)DecodedFrame) % width);¬
` dest -= (width<<1) + x;¬
` }¬
` {¬
` SOS_UINT32 *start = (SOS_UINT32*)DecodedFrame;¬
` size_t delta = dest - start;¬
` size_t x = delta % width;¬
` size_t y = delta / width;¬
` SOS_DEBUGOUT_FUNC_TRACE(¬
` " now at %ld %ld\n",¬
` x,y¬
` );¬
` }¬
`¬
` break;¬
` case 1: /* end of bitmap */¬
` SOS_DEBUGOUT_FUNC_TRACE("BMP escape eof\n");¬
` src+=2; /* consume two bytes */¬
` size-=2;¬
` goto rle8_done;¬
` case 2: /* delta */¬
` if (size<4) { /* need 3:0+dx+dy*/¬
` goto rle8_done;¬
` }¬
` SOS_DEBUGOUT_FUNC_TRACE(¬
` "BMP escape delta %d %d\n",¬
` src[2],¬
` src[3]¬
` );¬
` dest += src[2] - width * src[3];¬
` src+=4;¬
` size-=4;¬
` break;¬
` default: /* absolute mode */¬
`
`Page 4 of 10
`
`Implicit Exhibit 2044
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/bmpdecoder.c
`Page 5/10
`Saved: 9/6/01, 4:07:58 PM
`Printed for: Implicit
`
`170
`171
`172
`173
`174
`175
`176
`177
`178
`179
`180
`181
`182
`183
`184
`185
`186
`187
`188
`189
`190
`191
`192
`193
`194
`195
`196
`197
`198
`199
`200
`201
`202
`203
`204
`205
`206
`207
`208
`209
`210
`211
`212
`213
`214
`
` /* we need size[1] bytes to proceed */¬
` if (size<(SOS_UINT32)(src[1]+2)) {¬
` goto rle8_done;¬
` }¬
` SOS_DEBUGOUT_FUNC_TRACE(¬
` "BMP absolute %d\n",¬
` src[1]¬
` );¬
` count=src[1];¬
` src+=2;¬
` size-=2;¬
` while (count-->0) {¬
` if (dest>=destEnd) {¬
` status = SOS_ErrorFormat;¬
` goto rle8_done;¬
` }¬
` CHECK();¬
` RLE8_WRITE_PIXEL(*src++);¬
` size--;¬
` }¬
`¬
` {¬
` size_t length = src-(unsigned char *)EncodedFrame;¬
` align = WORD_ALIGN(length)-length;¬
` }¬
`¬
` ¬
` while (align--) {¬
` size--;¬
` src++;¬
` }¬
` }¬
` } else {¬
` /* first byte is not zero, run length encoding */¬
` SOS_DEBUGOUT_FUNC_TRACE(¬
` "BMP repeat %d %d\n",¬
` src[0],¬
` src[1]¬
` );¬
` count=*src++;¬
` size--;¬
` while (count-->0) {¬
` if (dest>=destEnd) {¬
` status = SOS_ErrorFormat;¬
` goto rle8_done;¬
`
`Page 5 of 10
`
`Implicit Exhibit 2044
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/bmpdecoder.c
`Page 6/10
`Saved: 9/6/01, 4:07:58 PM
`Printed for: Implicit
`
`215
`216
`217
`218
`219
`220
`221
`222
`223
`224
`225
`226
`227
`228
`229
`230
`231
`232
`233
`234
`235
`236
`237
`238
`239
`240
`241
`242
`243
`244
`245
`246
`247
`248
`249
`250
`251
`252
`253
`254
`255
`256
`257
`258
`259
`
` }¬
` CHECK();¬
` RLE8_WRITE_PIXEL(*src);¬
` }¬
` src++;¬
` size--;¬
` } ¬
` }¬
`¬
` rle8_done:¬
`¬
` SOS_DEBUGOUT_FUNC_TRACE(¬
` "decode %s, %d unused bytes\n",¬
` SOS_SUCCEEDED(status) ? "succeeded" : "failed",¬
` size¬
` );¬
`// SOS_ASSERT_ASSUMPTION(0,__func__);¬
` if (size>0) {¬
` status = SOS_ErrorFormat;¬
` }¬
`¬
` return status;¬
`}¬
`¬
`#define RGB(S) (S[0] | (S[1]<<8) | (S[2]<<16))¬
`¬
`static¬
`SOS_STATUS¬
`FrameDecode_Rgb(¬
` BMP_DECODER * BmpDecoder,¬
` void * EncodedFrame,¬
` size_t EncodedFrameSize,¬
` void * DecodedFrame,¬
` size_t DecodedFrameSize¬
`)¬
`{¬
` SOS_STATUS status = SOS_Success;¬
`¬
` size_t srcRemaining = EncodedFrameSize;¬
` ¬
` size_t destRemaining = DecodedFrameSize;¬
`¬
` /* invert the row order here */¬
` if (0) {¬
` /*¬
`
`Page 6 of 10
`
`Implicit Exhibit 2044
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/bmpdecoder.c
`Page 7/10
`Saved: 9/6/01, 4:07:58 PM
`Printed for: Implicit
`
`260
`261
`262
`263
`264
`265
`266
`267
`268
`269
`270
`271
`272
`273
`274
`275
`276
`277
`278
`279
`280
`281
`282
`283
`284
`285
`286
`287
`288
`289
`290
`291
`292
`293
`294
`295
`296
`…
`297
`298
`…
`299
`300
`301
`302
`
` * This is for uninverting 24->32 bit conversion¬
` */¬
` unsigned char *src = EncodedFrame;¬
` SOS_UINT32 *dest = DecodedFrame;¬
` /* non-inverting */¬
` while (srcRemaining>=3 && destRemaining>=4) {¬
` SOS_UINT32 rgb = 0;¬
` rgb = RGB(src);¬
` src+=3;¬
` *dest++=rgb;¬
` destRemaining-=4;¬
` srcRemaining-=3;¬
` }¬
` } else {¬
` /*¬
` * This is for inverting 24->32 bit conversion¬
` */¬
` SOS_UINT32 width = BmpDecoder->Format.Width;¬
` SOS_UINT32 height = BmpDecoder->Format.Height;¬
` unsigned char *src = EncodedFrame;¬
` SOS_UINT32 *dest = (SOS_UINT32*)DecodedFrame + ((height-1)*width);¬
` SOS_UINT32 x,y;¬
` SOS_UINT32 rgb = 0;¬
` for (y=height;y>0;y--) {¬
` for (x=width;x>0;x--) {¬
` rgb = RGB(src);¬
` src+=3;¬
` *dest++=rgb;¬
` }¬
` dest-=width*2;¬
` }¬
` }¬
` ¬
` return status;¬
`}¬
`¬
`/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`+++++¬
`External API¬
`++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
`+++*/¬
`¬
`BMP_DECODER *¬
`BmpDecoder_Create(¬
` void¬
`
`Page 7 of 10
`
`Implicit Exhibit 2044
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/bmpdecoder.c
`Page 8/10
`Saved: 9/6/01, 4:07:58 PM
`Printed for: Implicit
`
`303
`304
`305
`306
`307
`308
`309
`310
`311
`312
`313
`314
`315
`316
`317
`318
`319
`320
`321
`322
`323
`324
`325
`326
`327
`328
`329
`330
`331
`332
`333
`334
`335
`336
`337
`338
`339
`340
`341
`342
`343
`344
`345
`346
`347
`
`)¬
`{¬
` BMP_DECODER *decoder;¬
`¬
` decoder = SOS_Mem_Alloc(sizeof(BMP_DECODER));¬
` if (decoder) {¬
` SOS_memset(decoder, 0, sizeof(BMP_DECODER));¬
` }¬
`¬
` return decoder;¬
`}¬
`¬
`void¬
`BmpDecoder_Destroy(¬
` BMP_DECODER * BmpDecoder¬
`)¬
`{¬
` if (BmpDecoder) {¬
` if (BmpDecoder->ColorInfo) {¬
` SOS_Mem_Free(BmpDecoder->ColorInfo);¬
` }¬
` SOS_Mem_Free(BmpDecoder);¬
` }¬
`}¬
`¬
`SOS_STATUS¬
`BmpDecoder_FormatSet(¬
` BMP_DECODER * BmpDecoder,¬
` BMP_FORMAT * Format,¬
` void * ColorInfo,¬
` size_t ColorInfoSize¬
`)¬
`{¬
` SOS_STATUS status = SOS_Success;¬
` ¬
` BmpDecoder->FormatIsSet = SOS_True;¬
`¬
` SOS_memcpy(¬
` &(BmpDecoder->Format),¬
` Format,¬
` sizeof(BMP_FORMAT)¬
` );¬
`¬
` if (BmpDecoder->ColorInfo) {¬
` SOS_Mem_Free(BmpDecoder->ColorInfo);¬
`
`Page 8 of 10
`
`Implicit Exhibit 2044
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.01/b…/…/main/bmpdecoder.c
`Page 9/10
`Saved: 9/6/01, 4:07:58 PM
`Printed for: Implicit
`
`348
`349
`350
`351
`352
`353
`354
`355
`356
`357
`358
`359
`360
`361
`362
`363
`364
`365
`366
`367
`368
`369
`370
`371
`372
`373
`374
`375
`376
`377
`378
`379
`380
`381
`382
`383
`384
`385
`386
`387
`388
`389
`390
`391
`392
`
` }¬
` ¬
` BmpDecoder->ColorInfo = SOS_Mem_Alloc(ColorInfoSize);¬
` ¬
` if (BmpDecoder->ColorInfo) {¬
` SOS_memcpy(¬
` BmpDecoder->ColorInfo,¬
` ColorInfo,¬
` ColorInfoSize¬
` );¬
`¬
` } else {¬
` status = SOS_ErrorResourceAllocation;¬
` }¬
`¬
` return status;¬
`}¬
`¬
`SOS_STATUS¬
`BmpDecoder_FrameDecode(¬
` BMP_DECODER * BmpDecoder,¬
` void * EncodedFrame,¬
` size_t EncodedFrameSize,¬
` void * DecodedFrame,¬
` size_t DecodedFrameSize¬
`)¬
`{¬
` SOS_STATUS status;¬
`¬
` if (BmpDecoder->FormatIsSet) {¬
` switch (BmpDecoder->Format.Compression) {¬
` case BMP_BI_RLE8:¬
` status = FrameDecode_Rle8(¬
` BmpDecoder,¬
` EncodedFrame,¬
` EncodedFrameSize,¬
` DecodedFrame,¬
` DecodedFrameSize¬
` );¬
` break;¬
` case BMP_BI_RGB:¬
` status = FrameDecode_Rgb(¬
` BmpDecoder,¬
` EncodedFrame,¬
` EncodedFrameSize,¬
`
`Page 9 of 10
`
`Implicit Exhibit 2044
`Sonos v. Implicit, IPR2018-0766, -0767
`
`
`
`/Users/implicit/Desktop/Source Code/2001.11.…/…/…/main/bmpdecoder.c
`Page 10/10
`Saved: 9/6/01, 4:07:58 PM
`Printed for: Implicit
`
`393
`394
`395
`396
`397
`398
`399
`400
`401
`402
`403
`404
`405
`406
`407
`408
`409
`410
`411
`412
`413
`414
`415
`416
`417
`418
`419
`420
`421
`422
`423
`424
`425
`426
`427
`428
`429
`430
`431
`432
`433
`434
`435
`436
`437
`
` DecodedFrame,¬
` DecodedFrameSize¬
` );¬
` break;¬
` default:¬
` /* compression is not supported */¬
` status = SOS_ErrorFormat;¬
` }¬
` } else {¬
` /* format is not yet set */¬
` status = SOS_Error;¬
` }¬
` ¬
` return status;¬
`}¬
`¬
`SOS_STATUS¬
`BmpDecoder_FrameSizeGet(¬
` BMP_DECODER * BmpDecoder,¬
` size_t * FrameBufferSize¬
`)¬
`{¬
` SOS_STATUS status = SOS_Success;¬
` size_t size = 0;¬
` ¬
` if (BmpDecoder->FormatIsSet) {¬
` size = ¬
` BmpDecoder->Format.Width *¬
` BmpDecoder->Format.Height *¬
` sizeof(SOS_UINT32);¬
` } else {¬
` /* not yet set */¬
` status = SOS_Error;¬
` }¬
`¬
` if (FrameBufferSize) {¬
` *FrameBufferSize=size;¬
` }¬
`¬
` return status;¬
`}¬
` ¬
` ¬
`¬
`¬
`
`Page 10 of 10
`
`Implicit Exhibit 2044
`Sonos v. Implicit, IPR2018-0766, -0767
`
`