Guest User

Untitled

a guest
Apr 24th, 2017
116
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # HG changeset patch
  2. # User g3gg0
  3. # Date 1493076488 -7200
  4. #      Tue Apr 25 01:28:08 2017 +0200
  5. # Branch crop_rec_4k
  6. # Node ID 121d6fd2eb87cfe624d412c8a0cf2c49ae478b23
  7. # Parent  a5201c4146bfdc7d43106fae1bfa1c6c4769f267
  8. mlv_dump: add basic lossless decoding support, thanks martinhering (http://www.magiclantern.fm/forum/index.php?topic=19300.msg182502#msg182502)
  9.  
  10. diff -r a5201c4146bf -r 121d6fd2eb87 modules/mlv_rec/Makefile
  11. --- a/modules/mlv_rec/Makefile  Sun Apr 23 03:09:00 2017 +0300
  12. +++ b/modules/mlv_rec/Makefile  Tue Apr 25 01:28:08 2017 +0200
  13. @@ -6,7 +6,7 @@
  14.  # include modules environment
  15.  include ../Makefile.modules
  16.  
  17. -MLV_CFLAGS = -I$(SRC_DIR) -D MLV_USE_LZMA -m32 -Wpadded -mno-ms-bitfields -D _7ZIP_ST -D MLV2DNG
  18. +MLV_CFLAGS = -I$(SRC_DIR) -D MLV_USE_LZMA -D MLV_USE_LJ92 -m32 -Wpadded -mno-ms-bitfields -D _7ZIP_ST -D MLV2DNG
  19.  MLV_LFLAGS = -m32
  20.  MLV_LIBS = -lm
  21.  MLV_LIBS_MINGW = -lm
  22. @@ -44,7 +44,7 @@
  23.  MLV_LIBS += $(LZMA_LIB)
  24.  MLV_LIBS_MINGW += $(LZMA_LIB_MINGW)
  25.  
  26. -MLV_DUMP_OBJS=mlv_dump.host.o $(SRC_DIR)/chdk-dng.host.o ../lv_rec/raw2dng.host.o $(LZMA_LIB)
  27. +MLV_DUMP_OBJS=mlv_dump.host.o $(SRC_DIR)/chdk-dng.host.o ../lv_rec/raw2dng.host.o lj92.host.o $(LZMA_LIB)
  28.  MLV_DUMP_OBJS_MINGW=mlv_dump.w32.o $(SRC_DIR)/chdk-dng.w32.o ../lv_rec/raw2dng.w32.o $(LZMA_LIB_MINGW)
  29.  
  30.  
  31. diff -r a5201c4146bf -r 121d6fd2eb87 modules/mlv_rec/lj92.c
  32. --- /dev/null   Thu Jan 01 00:00:00 1970 +0000
  33. +++ b/modules/mlv_rec/lj92.c    Tue Apr 25 01:28:08 2017 +0200
  34. @@ -0,0 +1,1285 @@
  35. +/*
  36. + lj92.c
  37. + (c) Andrew Baldwin 2014
  38. +
  39. + Permission is hereby granted, free of charge, to any person obtaining a copy of
  40. + this software and associated documentation files (the "Software"), to deal in
  41. + the Software without restriction, including without limitation the rights to
  42. + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  43. + of the Software, and to permit persons to whom the Software is furnished to do
  44. + so, subject to the following conditions:
  45. +
  46. + The above copyright notice and this permission notice shall be included in all
  47. + copies or substantial portions of the Software.
  48. +
  49. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  50. + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  51. + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  52. + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  53. + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  54. + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  55. + SOFTWARE.
  56. + */
  57. +
  58. +#include <stdint.h>
  59. +#include <stdio.h>
  60. +#include <stdlib.h>
  61. +#include <string.h>
  62. +
  63. +#include "lj92.h"
  64. +
  65. +typedef uint8_t u8;
  66. +typedef uint16_t u16;
  67. +typedef uint32_t u32;
  68. +
  69. +//#define SLOW_HUFF
  70. +//#define LJ92_DEBUG
  71. +
  72. +#define assert(x)
  73. +#ifdef TINY_DNG_LOADER_DEBUG
  74. +#define DPRINTF(...) printf(__VA_ARGS__)
  75. +#else
  76. +#define DPRINTF(...)
  77. +#endif
  78. +
  79. +static int clz32(unsigned int x) {
  80. +    int n;
  81. +    if (x == 0) return 32;
  82. +    for (n = 0; ((x & 0x80000000) == 0); n++, x <<= 1)
  83. +        ;
  84. +    return n;
  85. +}
  86. +
  87. +
  88. +#define LJ92_MAX_COMPONENTS (16)
  89. +
  90. +typedef struct _ljp {
  91. +    u8* data;
  92. +    u8* dataend;
  93. +    int datalen;
  94. +    int scanstart;
  95. +    int ix;
  96. +    int x;           // Width
  97. +    int y;           // Height
  98. +    int bits;        // Bit depth
  99. +    int components;  // Components(Nf)
  100. +    int writelen;    // Write rows this long
  101. +    int skiplen;     // Skip this many values after each row
  102. +    u16* linearize;  // Linearization table
  103. +    int linlen;
  104. +    int sssshist[16];
  105. +
  106. +    // Huffman table - only one supported, and probably needed
  107. +#ifdef SLOW_HUFF
  108. +    // NOTE: Huffman table for each components is not supported for SLOW_HUFF code
  109. +    // path.
  110. +    int* maxcode;
  111. +    int* mincode;
  112. +    int* valptr;
  113. +    u8* huffval;
  114. +    int* huffsize;
  115. +    int* huffcode;
  116. +#else
  117. +    // Huffman table for each components
  118. +    u16* hufflut[LJ92_MAX_COMPONENTS];
  119. +    int huffbits[LJ92_MAX_COMPONENTS];
  120. +    int num_huff_idx;
  121. +#endif
  122. +    // Parse state
  123. +    int cnt;
  124. +    u32 b;
  125. +    u16* image;
  126. +    u16* rowcache;
  127. +    u16* outrow[2];
  128. +} ljp;
  129. +
  130. +static int find(ljp* self) {
  131. +    int ix = self->ix;
  132. +    u8* data = self->data;
  133. +    while (data[ix] != 0xFF && ix < (self->datalen - 1)) {
  134. +        ix += 1;
  135. +    }
  136. +    ix += 2;
  137. +    if (ix >= self->datalen) {
  138. +        // DPRINTF("idx = %d, datalen = %\d\n", ix, self->datalen);
  139. +        return -1;
  140. +    }
  141. +    self->ix = ix;
  142. +    // DPRINTF("ix = %d, data = %d\n", ix, data[ix - 1]);
  143. +    return data[ix - 1];
  144. +}
  145. +
  146. +#define BEH(ptr) ((((int)(*&ptr)) << 8) | (*(&ptr + 1)))
  147. +
  148. +static int parseHuff(ljp* self) {
  149. +    int ret = LJ92_ERROR_CORRUPT;
  150. +    u8* huffhead =
  151. +    &self->data
  152. +    [self->ix];  // xstruct.unpack('>HB16B',self.data[self.ix:self.ix+19])
  153. +    u8* bits = &huffhead[2];
  154. +    bits[0] = 0;  // Because table starts from 1
  155. +    int hufflen = BEH(huffhead[0]);
  156. +    if ((self->ix + hufflen) >= self->datalen) return ret;
  157. +#ifdef SLOW_HUFF
  158. +    u8* huffval = calloc(hufflen - 19, sizeof(u8));
  159. +    if (huffval == NULL) return LJ92_ERROR_NO_MEMORY;
  160. +    self->huffval = huffval;
  161. +    for (int hix = 0; hix < (hufflen - 19); hix++) {
  162. +        huffval[hix] = self->data[self->ix + 19 + hix];
  163. +#ifdef LJ92_DEBUG
  164. +        DPRINTF("huffval[%d]=%d\n", hix, huffval[hix]);
  165. +#endif
  166. +    }
  167. +    self->ix += hufflen;
  168. +    // Generate huffman table
  169. +    int k = 0;
  170. +    int i = 1;
  171. +    int j = 1;
  172. +    int huffsize_needed = 1;
  173. +    // First calculate how long huffsize needs to be
  174. +    while (i <= 16) {
  175. +        while (j <= bits[i]) {
  176. +            huffsize_needed++;
  177. +            k = k + 1;
  178. +            j = j + 1;
  179. +        }
  180. +        i = i + 1;
  181. +        j = 1;
  182. +    }
  183. +    // Now allocate and do it
  184. +    int* huffsize = calloc(huffsize_needed, sizeof(int));
  185. +    if (huffsize == NULL) return LJ92_ERROR_NO_MEMORY;
  186. +    self->huffsize = huffsize;
  187. +    k = 0;
  188. +    i = 1;
  189. +    j = 1;
  190. +    // First calculate how long huffsize needs to be
  191. +    int hsix = 0;
  192. +    while (i <= 16) {
  193. +        while (j <= bits[i]) {
  194. +            huffsize[hsix++] = i;
  195. +            k = k + 1;
  196. +            j = j + 1;
  197. +        }
  198. +        i = i + 1;
  199. +        j = 1;
  200. +    }
  201. +    huffsize[hsix++] = 0;
  202. +
  203. +    // Calculate the size of huffcode array
  204. +    int huffcode_needed = 0;
  205. +    k = 0;
  206. +    int code = 0;
  207. +    int si = huffsize[0];
  208. +    while (1) {
  209. +        while (huffsize[k] == si) {
  210. +            huffcode_needed++;
  211. +            code = code + 1;
  212. +            k = k + 1;
  213. +        }
  214. +        if (huffsize[k] == 0) break;
  215. +        while (huffsize[k] != si) {
  216. +            code = code << 1;
  217. +            si = si + 1;
  218. +        }
  219. +    }
  220. +    // Now fill it
  221. +    int* huffcode = calloc(huffcode_needed, sizeof(int));
  222. +    if (huffcode == NULL) return LJ92_ERROR_NO_MEMORY;
  223. +    self->huffcode = huffcode;
  224. +    int hcix = 0;
  225. +    k = 0;
  226. +    code = 0;
  227. +    si = huffsize[0];
  228. +    while (1) {
  229. +        while (huffsize[k] == si) {
  230. +            huffcode[hcix++] = code;
  231. +            code = code + 1;
  232. +            k = k + 1;
  233. +        }
  234. +        if (huffsize[k] == 0) break;
  235. +        while (huffsize[k] != si) {
  236. +            code = code << 1;
  237. +            si = si + 1;
  238. +        }
  239. +    }
  240. +
  241. +    i = 0;
  242. +    j = 0;
  243. +
  244. +    int* maxcode = calloc(17, sizeof(int));
  245. +    if (maxcode == NULL) return LJ92_ERROR_NO_MEMORY;
  246. +    self->maxcode = maxcode;
  247. +    int* mincode = calloc(17, sizeof(int));
  248. +    if (mincode == NULL) return LJ92_ERROR_NO_MEMORY;
  249. +    self->mincode = mincode;
  250. +    int* valptr = calloc(17, sizeof(int));
  251. +    if (valptr == NULL) return LJ92_ERROR_NO_MEMORY;
  252. +    self->valptr = valptr;
  253. +
  254. +    while (1) {
  255. +        while (1) {
  256. +            i++;
  257. +            if (i > 16) break;
  258. +            if (bits[i] != 0) break;
  259. +            maxcode[i] = -1;
  260. +        }
  261. +        if (i > 16) break;
  262. +        valptr[i] = j;
  263. +        mincode[i] = huffcode[j];
  264. +        j = j + bits[i] - 1;
  265. +        maxcode[i] = huffcode[j];
  266. +        j++;
  267. +    }
  268. +    free(huffsize);
  269. +    self->huffsize = NULL;
  270. +    free(huffcode);
  271. +    self->huffcode = NULL;
  272. +    ret = LJ92_ERROR_NONE;
  273. +#else
  274. +    /* Calculate huffman direct lut */
  275. +    // How many bits in the table - find highest entry
  276. +    u8* huffvals = &self->data[self->ix + 19];
  277. +    int maxbits = 16;
  278. +    while (maxbits > 0) {
  279. +        if (bits[maxbits]) break;
  280. +        maxbits--;
  281. +    }
  282. +    self->huffbits[self->num_huff_idx] = maxbits;
  283. +    /* Now fill the lut */
  284. +    u16* hufflut = (u16*)malloc((1 << maxbits) * sizeof(u16));
  285. +    // DPRINTF("maxbits = %d\n", maxbits);
  286. +    if (hufflut == NULL) return LJ92_ERROR_NO_MEMORY;
  287. +    self->hufflut[self->num_huff_idx] = hufflut;
  288. +    int i = 0;
  289. +    int hv = 0;
  290. +    int rv = 0;
  291. +    int vl = 0;  // i
  292. +    int hcode;
  293. +    int bitsused = 1;
  294. +#ifdef LJ92_DEBUG
  295. +    DPRINTF("%04x:%x:%d:%x\n", i, huffvals[hv], bitsused,
  296. +            1 << (maxbits - bitsused));
  297. +#endif
  298. +    while (i < 1 << maxbits) {
  299. +        if (bitsused > maxbits) {
  300. +            break;  // Done. Should never get here!
  301. +        }
  302. +        if (vl >= bits[bitsused]) {
  303. +            bitsused++;
  304. +            vl = 0;
  305. +            continue;
  306. +        }
  307. +        if (rv == 1 << (maxbits - bitsused)) {
  308. +            rv = 0;
  309. +            vl++;
  310. +            hv++;
  311. +#ifdef LJ92_DEBUG
  312. +            DPRINTF("%04x:%x:%d:%x\n", i, huffvals[hv], bitsused,
  313. +                    1 << (maxbits - bitsused));
  314. +#endif
  315. +            continue;
  316. +        }
  317. +        hcode = huffvals[hv];
  318. +        hufflut[i] = hcode << 8 | bitsused;
  319. +        // DPRINTF("%d %d %d\n",i,bitsused,hcode);
  320. +        i++;
  321. +        rv++;
  322. +    }
  323. +    ret = LJ92_ERROR_NONE;
  324. +#endif
  325. +    self->num_huff_idx++;
  326. +
  327. +    return ret;
  328. +}
  329. +
  330. +static int parseSof3(ljp* self) {
  331. +    if (self->ix + 6 >= self->datalen) return LJ92_ERROR_CORRUPT;
  332. +    self->y = BEH(self->data[self->ix + 3]);
  333. +    self->x = BEH(self->data[self->ix + 5]);
  334. +    self->bits = self->data[self->ix + 2];
  335. +    self->components = self->data[self->ix + 7];
  336. +    self->ix += BEH(self->data[self->ix]);
  337. +
  338. +    assert(self->components >= 1);
  339. +    assert(self->components < 6);
  340. +
  341. +    return LJ92_ERROR_NONE;
  342. +}
  343. +
  344. +static int parseBlock(ljp* self, int marker) {
  345. +    self->ix += BEH(self->data[self->ix]);
  346. +    if (self->ix >= self->datalen) {
  347. +        DPRINTF("parseBlock: ix %d, datalen %d\n", self->ix, self->datalen);
  348. +        return LJ92_ERROR_CORRUPT;
  349. +    }
  350. +    return LJ92_ERROR_NONE;
  351. +}
  352. +
  353. +#ifdef SLOW_HUFF
  354. +static int nextbit(ljp* self) {
  355. +    u32 b = self->b;
  356. +    if (self->cnt == 0) {
  357. +        u8* data = &self->data[self->ix];
  358. +        u32 next = *data++;
  359. +        b = next;
  360. +        if (next == 0xff) {
  361. +            data++;
  362. +            self->ix++;
  363. +        }
  364. +        self->ix++;
  365. +        self->cnt = 8;
  366. +    }
  367. +    int bit = b >> 7;
  368. +    self->cnt--;
  369. +    self->b = (b << 1) & 0xFF;
  370. +    return bit;
  371. +}
  372. +
  373. +static int decode(ljp* self) {
  374. +    int i = 1;
  375. +    int code = nextbit(self);
  376. +    while (code > self->maxcode[i]) {
  377. +        i++;
  378. +        code = (code << 1) + nextbit(self);
  379. +    }
  380. +    int j = self->valptr[i];
  381. +    j = j + code - self->mincode[i];
  382. +    int value = self->huffval[j];
  383. +    return value;
  384. +}
  385. +
  386. +static int receive(ljp* self, int ssss) {
  387. +    int i = 0;
  388. +    int v = 0;
  389. +    while (i != ssss) {
  390. +        i++;
  391. +        v = (v << 1) + nextbit(self);
  392. +    }
  393. +    return v;
  394. +}
  395. +
  396. +static int extend(ljp* self, int v, int t) {
  397. +    int vt = 1 << (t - 1);
  398. +    if (v < vt) {
  399. +        vt = (-1 << t) + 1;
  400. +        v = v + vt;
  401. +    }
  402. +    return v;
  403. +}
  404. +#endif
  405. +
  406. +inline static int nextdiff(ljp* self, int component_idx, int Px) {
  407. +#ifdef SLOW_HUFF
  408. +    int t = decode(self);
  409. +    int diff = receive(self, t);
  410. +    diff = extend(self, diff, t);
  411. +    // DPRINTF("%d %d %d %x\n",Px+diff,Px,diff,t);//,index,usedbits);
  412. +#else
  413. +    assert(component_idx <= self->num_huff_idx);
  414. +    u32 b = self->b;
  415. +    int cnt = self->cnt;
  416. +    int huffbits = self->huffbits[component_idx];
  417. +    int ix = self->ix;
  418. +    int next;
  419. +    while (cnt < huffbits) {
  420. +        next = *(u16*)&self->data[ix];
  421. +        int one = next & 0xFF;
  422. +        int two = next >> 8;
  423. +        b = (b << 16) | (one << 8) | two;
  424. +        cnt += 16;
  425. +        ix += 2;
  426. +        if (one == 0xFF) {
  427. +            // DPRINTF("%x %x %x %x %d\n",one,two,b,b>>8,cnt);
  428. +            b >>= 8;
  429. +            cnt -= 8;
  430. +        } else if (two == 0xFF)
  431. +            ix++;
  432. +    }
  433. +    int index = b >> (cnt - huffbits);
  434. +    // DPRINTF("component_idx = %d / %d, index = %d\n", component_idx,
  435. +    // self->components, index);
  436. +
  437. +    u16 ssssused = self->hufflut[component_idx][index];
  438. +    int usedbits = ssssused & 0xFF;
  439. +    int t = ssssused >> 8;
  440. +    self->sssshist[t]++;
  441. +    cnt -= usedbits;
  442. +    int keepbitsmask = (1 << cnt) - 1;
  443. +    b &= keepbitsmask;
  444. +    while (cnt < t) {
  445. +        next = *(u16*)&self->data[ix];
  446. +        int one = next & 0xFF;
  447. +        int two = next >> 8;
  448. +        b = (b << 16) | (one << 8) | two;
  449. +        cnt += 16;
  450. +        ix += 2;
  451. +        if (one == 0xFF) {
  452. +            b >>= 8;
  453. +            cnt -= 8;
  454. +        } else if (two == 0xFF)
  455. +            ix++;
  456. +    }
  457. +    cnt -= t;
  458. +    int diff = b >> cnt;
  459. +    int vt = 1 << (t - 1);
  460. +    if (diff < vt) {
  461. +        vt = (-1 << t) + 1;
  462. +        diff += vt;
  463. +    }
  464. +    keepbitsmask = (1 << cnt) - 1;
  465. +    self->b = b & keepbitsmask;
  466. +    self->cnt = cnt;
  467. +    self->ix = ix;
  468. +    // DPRINTF("%d %d\n",t,diff);
  469. +    // DPRINTF("%d %d %d %x %x %d\n",Px+diff,Px,diff,t,index,usedbits);
  470. +#ifdef LJ92_DEBUG
  471. +#endif
  472. +#endif
  473. +    return diff;
  474. +}
  475. +
  476. +static int parsePred6(ljp* self) {
  477. +    DPRINTF("parsePred6\n");
  478. +    int ret = LJ92_ERROR_CORRUPT;
  479. +    self->ix = self->scanstart;
  480. +    // int compcount = self->data[self->ix+2];
  481. +    self->ix += BEH(self->data[self->ix]);
  482. +    self->cnt = 0;
  483. +    self->b = 0;
  484. +    int write = self->writelen;
  485. +    // Now need to decode huffman coded values
  486. +    int c = 0;
  487. +    int pixels = self->y * self->x;
  488. +    u16* out = self->image;
  489. +    u16* temprow;
  490. +    u16* thisrow = self->outrow[0];
  491. +    u16* lastrow = self->outrow[1];
  492. +
  493. +    // First pixel predicted from base value
  494. +    int diff;
  495. +    int Px;
  496. +    int col = 0;
  497. +    int row = 0;
  498. +    int left = 0;
  499. +    int linear;
  500. +
  501. +    assert(self->num_huff_idx <= self->components);
  502. +    // First pixel
  503. +    diff = nextdiff(self, self->num_huff_idx - 1,
  504. +                    0);  // FIXME(syoyo): Is using (self->num_huff_idx-1) correct?
  505. +    Px = 1 << (self->bits - 1);
  506. +    left = Px + diff;
  507. +    if (self->linearize)
  508. +        linear = self->linearize[left];
  509. +    else
  510. +        linear = left;
  511. +    thisrow[col++] = left;
  512. +    out[c++] = linear;
  513. +    if (self->ix >= self->datalen) {
  514. +        DPRINTF("ix = %d, datalen = %d\n", self->ix, self->datalen);
  515. +        return ret;
  516. +    }
  517. +    --write;
  518. +    int rowcount = self->x - 1;
  519. +    while (rowcount--) {
  520. +        diff = nextdiff(self, self->num_huff_idx - 1, 0);
  521. +        Px = left;
  522. +        left = Px + diff;
  523. +        if (self->linearize)
  524. +            linear = self->linearize[left];
  525. +        else
  526. +            linear = left;
  527. +        thisrow[col++] = left;
  528. +        out[c++] = linear;
  529. +        // DPRINTF("%d %d %d %d
  530. +        // %x\n",col-1,diff,left,thisrow[col-1],&thisrow[col-1]);
  531. +        if (self->ix >= self->datalen) {
  532. +            DPRINTF("a: self->ix = %d, datalen = %d\n", self->ix, self->datalen);
  533. +            return ret;
  534. +        }
  535. +        if (--write == 0) {
  536. +            out += self->skiplen;
  537. +            write = self->writelen;
  538. +        }
  539. +    }
  540. +    temprow = lastrow;
  541. +    lastrow = thisrow;
  542. +    thisrow = temprow;
  543. +    row++;
  544. +    // DPRINTF("%x %x\n",thisrow,lastrow);
  545. +    while (c < pixels) {
  546. +        col = 0;
  547. +        diff = nextdiff(self, self->num_huff_idx - 1, 0);
  548. +        Px = lastrow[col];  // Use value above for first pixel in row
  549. +        left = Px + diff;
  550. +        if (self->linearize) {
  551. +            if (left > self->linlen) return LJ92_ERROR_CORRUPT;
  552. +            linear = self->linearize[left];
  553. +        } else
  554. +            linear = left;
  555. +        thisrow[col++] = left;
  556. +        // DPRINTF("%d %d %d %d\n",col,diff,left,lastrow[col]);
  557. +        out[c++] = linear;
  558. +        if (self->ix >= self->datalen) break;
  559. +        rowcount = self->x - 1;
  560. +        if (--write == 0) {
  561. +            out += self->skiplen;
  562. +            write = self->writelen;
  563. +        }
  564. +        while (rowcount--) {
  565. +            diff = nextdiff(self, self->num_huff_idx - 1, 0);
  566. +            Px = lastrow[col] + ((left - lastrow[col - 1]) >> 1);
  567. +            left = Px + diff;
  568. +            // DPRINTF("%d %d %d %d %d
  569. +            // %x\n",col,diff,left,lastrow[col],lastrow[col-1],&lastrow[col]);
  570. +            if (self->linearize) {
  571. +                if (left > self->linlen) return LJ92_ERROR_CORRUPT;
  572. +                linear = self->linearize[left];
  573. +            } else
  574. +                linear = left;
  575. +            thisrow[col++] = left;
  576. +            out[c++] = linear;
  577. +            if (--write == 0) {
  578. +                out += self->skiplen;
  579. +                write = self->writelen;
  580. +            }
  581. +        }
  582. +        temprow = lastrow;
  583. +        lastrow = thisrow;
  584. +        thisrow = temprow;
  585. +        if (self->ix >= self->datalen) break;
  586. +    }
  587. +    if (c >= pixels) ret = LJ92_ERROR_NONE;
  588. +    return ret;
  589. +}
  590. +
  591. +static int parseScan(ljp* self) {
  592. +    int ret = LJ92_ERROR_CORRUPT;
  593. +    memset(self->sssshist, 0, sizeof(self->sssshist));
  594. +    self->ix = self->scanstart;
  595. +    int compcount = self->data[self->ix + 2];
  596. +    int pred = self->data[self->ix + 3 + 2 * compcount];
  597. +    if (pred < 0 || pred > 7) return ret;
  598. +    if (pred == 6) return parsePred6(self);  // Fast path
  599. +    // DPRINTF("pref = %d\n", pred);
  600. +    self->ix += BEH(self->data[self->ix]);
  601. +    self->cnt = 0;
  602. +    self->b = 0;
  603. +    // int write = self->writelen;
  604. +    // Now need to decode huffman coded values
  605. +    // int c = 0;
  606. +    // int pixels = self->y * self->x * self->components;
  607. +    u16* out = self->image;
  608. +    u16* thisrow = self->outrow[0];
  609. +    u16* lastrow = self->outrow[1];
  610. +
  611. +    // First pixel predicted from base value
  612. +    int diff;
  613. +    int Px = 0;
  614. +    // int col = 0;
  615. +    // int row = 0;
  616. +    int left = 0;
  617. +    // DPRINTF("w = %d, h = %d, components = %d, skiplen = %d\n", self->x,
  618. +    // self->y,
  619. +    //       self->components, self->skiplen);
  620. +    for (int row = 0; row < self->y; row++) {
  621. +        // DPRINTF("row = %d / %d\n", row, self->y);
  622. +        for (int col = 0; col < self->x; col++) {
  623. +            int colx = col * self->components;
  624. +            for (int c = 0; c < self->components; c++) {
  625. +                // DPRINTF("c = %d, col = %d, row = %d\n", c, col, row);
  626. +                if ((col == 0) && (row == 0)) {
  627. +                    Px = 1 << (self->bits - 1);
  628. +                } else if (row == 0) {
  629. +                    // Px = left;
  630. +                    assert(col > 0);
  631. +                    Px = thisrow[(col - 1) * self->components + c];
  632. +                } else if (col == 0) {
  633. +                    Px = lastrow[c];  // Use value above for first pixel in row
  634. +                } else {
  635. +                    int prev_colx = (col - 1) * self->components;
  636. +                    // DPRINTF("pred = %d\n", pred);
  637. +                    switch (pred) {
  638. +                        case 0:
  639. +                            Px = 0;
  640. +                            break;  // No prediction... should not be used
  641. +                        case 1:
  642. +                            Px = thisrow[prev_colx + c];
  643. +                            break;
  644. +                        case 2:
  645. +                            Px = lastrow[colx + c];
  646. +                            break;
  647. +                        case 3:
  648. +                            Px = lastrow[prev_colx + c];
  649. +                            break;
  650. +                        case 4:
  651. +                            Px = left + lastrow[colx + c] - lastrow[prev_colx + c];
  652. +                            break;
  653. +                        case 5:
  654. +                            Px = left + ((lastrow[colx + c] - lastrow[prev_colx + c]) >> 1);
  655. +                            break;
  656. +                        case 6:
  657. +                            Px = lastrow[colx + c] + ((left - lastrow[prev_colx + c]) >> 1);
  658. +                            break;
  659. +                        case 7:
  660. +                            Px = (left + lastrow[colx + c]) >> 1;
  661. +                            break;
  662. +                    }
  663. +                }
  664. +
  665. +                int huff_idx = c;
  666. +                if (c >= self->num_huff_idx) {
  667. +                    // It looks huffman tables are shared for all components.
  668. +                    // Currently we assume # of huffman tables is 1.
  669. +                    assert(self->num_huff_idx == 1);
  670. +                    huff_idx = 0;  // Look up the first huffman table.
  671. +                }
  672. +
  673. +                diff = nextdiff(self, huff_idx, Px);
  674. +                left = Px + diff;
  675. +                // DPRINTF("c[%d] Px = %d, diff = %d, left = %d\n", c, Px, diff, left);
  676. +                assert(left >= 0);
  677. +                assert(left < (1 << self->bits));
  678. +                // DPRINTF("pix = %d\n", left);
  679. +                // DPRINTF("%d %d %d\n",c,diff,left);
  680. +                int linear;
  681. +                if (self->linearize) {
  682. +                    if (left > self->linlen) return LJ92_ERROR_CORRUPT;
  683. +                    linear = self->linearize[left];
  684. +                } else {
  685. +                    linear = left;
  686. +                }
  687. +
  688. +                // DPRINTF("linear = %d\n", linear);
  689. +                thisrow[colx + c] = left;
  690. +                out[colx + c] = linear;  // HACK
  691. +            }                          // c
  692. +        }                            // col
  693. +
  694. +        u16* temprow = lastrow;
  695. +        lastrow = thisrow;
  696. +        thisrow = temprow;
  697. +
  698. +        out += self->x * self->components + self->skiplen;
  699. +        // out += self->skiplen;
  700. +        // DPRINTF("out = %p, %p, diff = %lld\n", out, self->image, out -
  701. +        // self->image);
  702. +
  703. +    }  // row
  704. +
  705. +    ret = LJ92_ERROR_NONE;
  706. +
  707. +    // if (++col == self->x) {
  708. +    // col = 0;
  709. +    // row++;
  710. +    //}
  711. +    // if (--write == 0) {
  712. +    // out += self->skiplen;
  713. +    // write = self->writelen;
  714. +    //}
  715. +    // if (self->ix >= self->datalen + 2) break;
  716. +
  717. +    // if (c >= pixels) ret = LJ92_ERROR_NONE;
  718. +    /*for (int h=0;h<17;h++) {
  719. +     DPRINTF("ssss:%d=%d
  720. +     (%f)\n",h,self->sssshist[h],(float)self->sssshist[h]/(float)(pixels));
  721. +     }*/
  722. +    return ret;
  723. +}
  724. +
  725. +static int parseImage(ljp* self) {
  726. +    // DPRINTF("parseImage\n");
  727. +    int ret = LJ92_ERROR_NONE;
  728. +    while (1) {
  729. +        int nextMarker = find(self);
  730. +        DPRINTF("marker = 0x%08x\n", nextMarker);
  731. +        if (nextMarker == 0xc4)
  732. +            ret = parseHuff(self);
  733. +        else if (nextMarker == 0xc3)
  734. +            ret = parseSof3(self);
  735. +        else if (nextMarker == 0xfe)  // Comment
  736. +            ret = parseBlock(self, nextMarker);
  737. +        else if (nextMarker == 0xd9)  // End of image
  738. +            break;
  739. +        else if (nextMarker == 0xda) {
  740. +            self->scanstart = self->ix;
  741. +            ret = LJ92_ERROR_NONE;
  742. +            break;
  743. +        } else if (nextMarker == -1) {
  744. +            ret = LJ92_ERROR_CORRUPT;
  745. +            break;
  746. +        } else
  747. +            ret = parseBlock(self, nextMarker);
  748. +        if (ret != LJ92_ERROR_NONE) break;
  749. +    }
  750. +    return ret;
  751. +}
  752. +
  753. +static int findSoI(ljp* self) {
  754. +    int ret = LJ92_ERROR_CORRUPT;
  755. +    if (find(self) == 0xd8) {
  756. +        ret = parseImage(self);
  757. +    } else {
  758. +        DPRINTF("findSoI: corrupt\n");
  759. +    }
  760. +    return ret;
  761. +}
  762. +
  763. +static void free_memory(ljp* self) {
  764. +#ifdef SLOW_HUFF
  765. +    free(self->maxcode);
  766. +    self->maxcode = NULL;
  767. +    free(self->mincode);
  768. +    self->mincode = NULL;
  769. +    free(self->valptr);
  770. +    self->valptr = NULL;
  771. +    free(self->huffval);
  772. +    self->huffval = NULL;
  773. +    free(self->huffsize);
  774. +    self->huffsize = NULL;
  775. +    free(self->huffcode);
  776. +    self->huffcode = NULL;
  777. +#else
  778. +    for (int i = 0; i < self->num_huff_idx; i++) {
  779. +        free(self->hufflut[i]);
  780. +        self->hufflut[i] = NULL;
  781. +    }
  782. +#endif
  783. +    free(self->rowcache);
  784. +    self->rowcache = NULL;
  785. +}
  786. +
  787. +int lj92_open(lj92* lj, const uint8_t* data, int datalen, int* width,
  788. +              int* height, int* bitdepth, int* components) {
  789. +    ljp* self = (ljp*)calloc(sizeof(ljp), 1);
  790. +    if (self == NULL) return LJ92_ERROR_NO_MEMORY;
  791. +
  792. +    self->data = (u8*)data;
  793. +    self->dataend = self->data + datalen;
  794. +    self->datalen = datalen;
  795. +    self->num_huff_idx = 0;
  796. +
  797. +    int ret = findSoI(self);
  798. +
  799. +    if (ret == LJ92_ERROR_NONE) {
  800. +        u16* rowcache = (u16*)calloc(self->x * self->components * 2, sizeof(u16));
  801. +        if (rowcache == NULL)
  802. +            ret = LJ92_ERROR_NO_MEMORY;
  803. +        else {
  804. +            self->rowcache = rowcache;
  805. +            self->outrow[0] = rowcache;
  806. +            self->outrow[1] = &rowcache[self->x];
  807. +        }
  808. +    }
  809. +
  810. +    if (ret != LJ92_ERROR_NONE) {  // Failed, clean up
  811. +        *lj = NULL;
  812. +        free_memory(self);
  813. +        free(self);
  814. +    } else {
  815. +        *width = self->x;
  816. +        *height = self->y;
  817. +        *bitdepth = self->bits;
  818. +        *components = self->components;
  819. +        *lj = self;
  820. +    }
  821. +    return ret;
  822. +}
  823. +
  824. +int lj92_decode(lj92 lj, uint16_t* target, int writeLength, int skipLength,
  825. +                uint16_t* linearize, int linearizeLength) {
  826. +    int ret = LJ92_ERROR_NONE;
  827. +    ljp* self = lj;
  828. +    if (self == NULL) return LJ92_ERROR_BAD_HANDLE;
  829. +    self->image = target;
  830. +    self->writelen = writeLength;
  831. +    self->skiplen = skipLength;
  832. +    self->linearize = linearize;
  833. +    self->linlen = linearizeLength;
  834. +    ret = parseScan(self);
  835. +    return ret;
  836. +}
  837. +
  838. +void lj92_close(lj92 lj) {
  839. +    ljp* self = lj;
  840. +    if (self != NULL) free_memory(self);
  841. +    free(self);
  842. +}
  843. +
  844. +/* Encoder implementation */
  845. +
  846. +typedef struct _lje {
  847. +    uint16_t* image;
  848. +    int width;
  849. +    int height;
  850. +    int bitdepth;
  851. +    int components;
  852. +    int readLength;
  853. +    int skipLength;
  854. +    uint16_t* delinearize;
  855. +    int delinearizeLength;
  856. +    uint8_t* encoded;
  857. +    int encodedWritten;
  858. +    int encodedLength;
  859. +    int hist[17];  // SSSS frequency histogram
  860. +    int bits[17];
  861. +    int huffval[17];
  862. +    u16 huffenc[17];
  863. +    u16 huffbits[17];
  864. +    int huffsym[17];
  865. +} lje;
  866. +
  867. +int frequencyScan(lje* self) {
  868. +    // Scan through the tile using the standard type 6 prediction
  869. +    // Need to cache the previous 2 row in target coordinates because of tiling
  870. +    uint16_t* pixel = self->image;
  871. +    int pixcount = self->width * self->height;
  872. +    int scan = self->readLength;
  873. +    uint16_t* rowcache = (uint16_t*)calloc(1, self->width * self->components * 4);
  874. +    uint16_t* rows[2];
  875. +    rows[0] = rowcache;
  876. +    rows[1] = &rowcache[self->width];
  877. +
  878. +    int col = 0;
  879. +    int row = 0;
  880. +    int Px = 0;
  881. +    int32_t diff = 0;
  882. +    int maxval = (1 << self->bitdepth);
  883. +    while (pixcount--) {
  884. +        uint16_t p = *pixel;
  885. +        if (self->delinearize) {
  886. +            if (p >= self->delinearizeLength) {
  887. +                free(rowcache);
  888. +                return LJ92_ERROR_TOO_WIDE;
  889. +            }
  890. +            p = self->delinearize[p];
  891. +        }
  892. +        if (p >= maxval) {
  893. +            free(rowcache);
  894. +            return LJ92_ERROR_TOO_WIDE;
  895. +        }
  896. +        rows[1][col] = p;
  897. +
  898. +        if ((row == 0) && (col == 0))
  899. +            Px = 1 << (self->bitdepth - 1);
  900. +        else if (row == 0)
  901. +            Px = rows[1][col - 1];
  902. +        else if (col == 0)
  903. +            Px = rows[0][col];
  904. +        else
  905. +            Px = rows[0][col] + ((rows[1][col - 1] - rows[0][col - 1]) >> 1);
  906. +        diff = rows[1][col] - Px;
  907. +        // int ssss = 32 - __builtin_clz(abs(diff));
  908. +        int ssss = 32 - clz32(abs(diff));
  909. +        if (diff == 0) ssss = 0;
  910. +        self->hist[ssss]++;
  911. +        // DPRINTF("%d %d %d %d %d %d\n",col,row,p,Px,diff,ssss);
  912. +        pixel++;
  913. +        scan--;
  914. +        col++;
  915. +        if (scan == 0) {
  916. +            pixel += self->skipLength;
  917. +            scan = self->readLength;
  918. +        }
  919. +        if (col == self->width) {
  920. +            uint16_t* tmprow = rows[1];
  921. +            rows[1] = rows[0];
  922. +            rows[0] = tmprow;
  923. +            col = 0;
  924. +            row++;
  925. +        }
  926. +    }
  927. +#ifdef LJ92_DEBUG
  928. +    int sort[17];
  929. +    for (int h = 0; h < 17; h++) {
  930. +        sort[h] = h;
  931. +        DPRINTF("%d:%d\n", h, self->hist[h]);
  932. +    }
  933. +#endif
  934. +    free(rowcache);
  935. +    return LJ92_ERROR_NONE;
  936. +}
  937. +
  938. +void createEncodeTable(lje* self) {
  939. +    float freq[18];
  940. +    int codesize[18];
  941. +    int others[18];
  942. +
  943. +    // Calculate frequencies
  944. +    float totalpixels = self->width * self->height;
  945. +    for (int i = 0; i < 17; i++) {
  946. +        freq[i] = (float)(self->hist[i]) / totalpixels;
  947. +#ifdef LJ92_DEBUG
  948. +        DPRINTF("%d:%f\n", i, freq[i]);
  949. +#endif
  950. +        codesize[i] = 0;
  951. +        others[i] = -1;
  952. +    }
  953. +    codesize[17] = 0;
  954. +    others[17] = -1;
  955. +    freq[17] = 1.0f;
  956. +
  957. +    float v1f, v2f;
  958. +    int v1, v2;
  959. +
  960. +    while (1) {
  961. +        v1f = 3.0f;
  962. +        v1 = -1;
  963. +        for (int i = 0; i < 18; i++) {
  964. +            if ((freq[i] <= v1f) && (freq[i] > 0.0f)) {
  965. +                v1f = freq[i];
  966. +                v1 = i;
  967. +            }
  968. +        }
  969. +#ifdef LJ92_DEBUG
  970. +        DPRINTF("v1:%d,%f\n", v1, v1f);
  971. +#endif
  972. +        v2f = 3.0f;
  973. +        v2 = -1;
  974. +        for (int i = 0; i < 18; i++) {
  975. +            if (i == v1) continue;
  976. +            if ((freq[i] < v2f) && (freq[i] > 0.0f)) {
  977. +                v2f = freq[i];
  978. +                v2 = i;
  979. +            }
  980. +        }
  981. +        if (v2 == -1) break;  // Done
  982. +
  983. +        freq[v1] += freq[v2];
  984. +        freq[v2] = 0.0f;
  985. +
  986. +        while (1) {
  987. +            codesize[v1]++;
  988. +            if (others[v1] == -1) break;
  989. +            v1 = others[v1];
  990. +        }
  991. +        others[v1] = v2;
  992. +        while (1) {
  993. +            codesize[v2]++;
  994. +            if (others[v2] == -1) break;
  995. +            v2 = others[v2];
  996. +        }
  997. +    }
  998. +    int* bits = self->bits;
  999. +    memset(bits, 0, sizeof(self->bits));
  1000. +    for (int i = 0; i < 18; i++) {
  1001. +        if (codesize[i] != 0) {
  1002. +            bits[codesize[i]]++;
  1003. +        }
  1004. +    }
  1005. +#ifdef LJ92_DEBUG
  1006. +    for (int i = 0; i < 17; i++) {
  1007. +        DPRINTF("bits:%d,%d,%d\n", i, bits[i], codesize[i]);
  1008. +    }
  1009. +#endif
  1010. +    int* huffval = self->huffval;
  1011. +    int i = 1;
  1012. +    int k = 0;
  1013. +    int j;
  1014. +    memset(huffval, 0, sizeof(self->huffval));
  1015. +    while (i <= 32) {
  1016. +        j = 0;
  1017. +        while (j < 17) {
  1018. +            if (codesize[j] == i) {
  1019. +                huffval[k++] = j;
  1020. +            }
  1021. +            j++;
  1022. +        }
  1023. +        i++;
  1024. +    }
  1025. +#ifdef LJ92_DEBUG
  1026. +    for (i = 0; i < 17; i++) {
  1027. +        DPRINTF("i=%d,huffval[i]=%x\n", i, huffval[i]);
  1028. +    }
  1029. +#endif
  1030. +    int maxbits = 16;
  1031. +    while (maxbits > 0) {
  1032. +        if (bits[maxbits]) break;
  1033. +        maxbits--;
  1034. +    }
  1035. +    u16* huffenc = self->huffenc;
  1036. +    u16* huffbits = self->huffbits;
  1037. +    int* huffsym = self->huffsym;
  1038. +    memset(huffenc, 0, sizeof(self->huffenc));
  1039. +    memset(huffbits, 0, sizeof(self->huffbits));
  1040. +    memset(self->huffsym, 0, sizeof(self->huffsym));
  1041. +    i = 0;
  1042. +    int hv = 0;
  1043. +    int rv = 0;
  1044. +    int vl = 0;  // i
  1045. +    // int hcode;
  1046. +    int bitsused = 1;
  1047. +    int sym = 0;
  1048. +    // DPRINTF("%04x:%x:%d:%x\n",i,huffvals[hv],bitsused,1<<(maxbits-bitsused));
  1049. +    while (i < 1 << maxbits) {
  1050. +        if (bitsused > maxbits) {
  1051. +            break;  // Done. Should never get here!
  1052. +        }
  1053. +        if (vl >= bits[bitsused]) {
  1054. +            bitsused++;
  1055. +            vl = 0;
  1056. +            continue;
  1057. +        }
  1058. +        if (rv == 1 << (maxbits - bitsused)) {
  1059. +            rv = 0;
  1060. +            vl++;
  1061. +            hv++;
  1062. +            // DPRINTF("%04x:%x:%d:%x\n",i,huffvals[hv],bitsused,1<<(maxbits-bitsused));
  1063. +            continue;
  1064. +        }
  1065. +        huffbits[sym] = bitsused;
  1066. +        huffenc[sym++] = i >> (maxbits - bitsused);
  1067. +        // DPRINTF("%d %d %d\n",i,bitsused,hcode);
  1068. +        i += (1 << (maxbits - bitsused));
  1069. +        rv = 1 << (maxbits - bitsused);
  1070. +    }
  1071. +    for (i = 0; i < 17; i++) {
  1072. +        if (huffbits[i] > 0) {
  1073. +            huffsym[huffval[i]] = i;
  1074. +        }
  1075. +#ifdef LJ92_DEBUG
  1076. +        DPRINTF("huffval[%d]=%d,huffenc[%d]=%x,bits=%d\n", i, huffval[i], i,
  1077. +                huffenc[i], huffbits[i]);
  1078. +#endif
  1079. +        if (huffbits[i] > 0) {
  1080. +            huffsym[huffval[i]] = i;
  1081. +        }
  1082. +    }
  1083. +#ifdef LJ92_DEBUG
  1084. +    for (i = 0; i < 17; i++) {
  1085. +        DPRINTF("huffsym[%d]=%d\n", i, huffsym[i]);
  1086. +    }
  1087. +#endif
  1088. +}
  1089. +
  1090. +void writeHeader(lje* self) {
  1091. +    int w = self->encodedWritten;
  1092. +    uint8_t* e = self->encoded;
  1093. +    e[w++] = 0xff;
  1094. +    e[w++] = 0xd8;  // SOI
  1095. +    e[w++] = 0xff;
  1096. +    e[w++] = 0xc3;  // SOF3
  1097. +    // Write SOF
  1098. +    e[w++] = 0x0;
  1099. +    e[w++] = 11;  // Lf, frame header length
  1100. +    e[w++] = self->bitdepth;
  1101. +    e[w++] = self->height >> 8;
  1102. +    e[w++] = self->height & 0xFF;
  1103. +    e[w++] = self->width >> 8;
  1104. +    e[w++] = self->width & 0xFF;
  1105. +    e[w++] = 1;     // Components
  1106. +    e[w++] = 0;     // Component ID
  1107. +    e[w++] = 0x11;  // Component X/Y
  1108. +    e[w++] = 0;     // Unused (Quantisation)
  1109. +    e[w++] = 0xff;
  1110. +    e[w++] = 0xc4;  // HUFF
  1111. +    // Write HUFF
  1112. +    int count = 0;
  1113. +    for (int i = 0; i < 17; i++) {
  1114. +        count += self->bits[i];
  1115. +    }
  1116. +    e[w++] = 0x0;
  1117. +    e[w++] = 17 + 2 + count;  // Lf, frame header length
  1118. +    e[w++] = 0;               // Table ID
  1119. +    for (int i = 1; i < 17; i++) {
  1120. +        e[w++] = self->bits[i];
  1121. +    }
  1122. +    for (int i = 0; i < count; i++) {
  1123. +        e[w++] = self->huffval[i];
  1124. +    }
  1125. +    e[w++] = 0xff;
  1126. +    e[w++] = 0xda;  // SCAN
  1127. +    // Write SCAN
  1128. +    e[w++] = 0x0;
  1129. +    e[w++] = 8;  // Ls, scan header length
  1130. +    e[w++] = 1;  // Components
  1131. +    e[w++] = 0;  //
  1132. +    e[w++] = 0;  //
  1133. +    e[w++] = 6;  // Predictor
  1134. +    e[w++] = 0;  //
  1135. +    e[w++] = 0;  //
  1136. +    self->encodedWritten = w;
  1137. +}
  1138. +
  1139. +void writePost(lje* self) {
  1140. +    int w = self->encodedWritten;
  1141. +    uint8_t* e = self->encoded;
  1142. +    e[w++] = 0xff;
  1143. +    e[w++] = 0xd9;  // EOI
  1144. +    self->encodedWritten = w;
  1145. +}
  1146. +
  1147. +void writeBody(lje* self) {
  1148. +    // Scan through the tile using the standard type 6 prediction
  1149. +    // Need to cache the previous 2 row in target coordinates because of tiling
  1150. +    uint16_t* pixel = self->image;
  1151. +    int pixcount = self->width * self->height;
  1152. +    int scan = self->readLength;
  1153. +    uint16_t* rowcache = (uint16_t*)calloc(1, self->width * self->components * 4);
  1154. +    uint16_t* rows[2];
  1155. +    rows[0] = rowcache;
  1156. +    rows[1] = &rowcache[self->width];
  1157. +
  1158. +    int col = 0;
  1159. +    int row = 0;
  1160. +    int Px = 0;
  1161. +    int32_t diff = 0;
  1162. +    int bitcount = 0;
  1163. +    uint8_t* out = self->encoded;
  1164. +    int w = self->encodedWritten;
  1165. +    uint8_t next = 0;
  1166. +    uint8_t nextbits = 8;
  1167. +    while (pixcount--) {
  1168. +        uint16_t p = *pixel;
  1169. +        if (self->delinearize) p = self->delinearize[p];
  1170. +        rows[1][col] = p;
  1171. +
  1172. +        if ((row == 0) && (col == 0))
  1173. +            Px = 1 << (self->bitdepth - 1);
  1174. +        else if (row == 0)
  1175. +            Px = rows[1][col - 1];
  1176. +        else if (col == 0)
  1177. +            Px = rows[0][col];
  1178. +        else
  1179. +            Px = rows[0][col] + ((rows[1][col - 1] - rows[0][col - 1]) >> 1);
  1180. +        diff = rows[1][col] - Px;
  1181. +        // int ssss = 32 - __builtin_clz(abs(diff));
  1182. +        int ssss = 32 - clz32(abs(diff));
  1183. +        if (diff == 0) ssss = 0;
  1184. +        // DPRINTF("%d %d %d %d %d\n",col,row,Px,diff,ssss);
  1185. +
  1186. +        // Write the huffman code for the ssss value
  1187. +        int huffcode = self->huffsym[ssss];
  1188. +        int huffenc = self->huffenc[huffcode];
  1189. +        int huffbits = self->huffbits[huffcode];
  1190. +        bitcount += huffbits + ssss;
  1191. +        
  1192. +        int vt = ssss > 0 ? (1 << (ssss - 1)) : 0;
  1193. +        // DPRINTF("%d %d %d %d\n",rows[1][col],Px,diff,Px+diff);
  1194. +#ifdef LJ92_DEBUG
  1195. +#endif
  1196. +        if (diff < vt) diff += (1 << (ssss)) - 1;
  1197. +        
  1198. +        // Write the ssss
  1199. +        while (huffbits > 0) {
  1200. +            int usebits = huffbits > nextbits ? nextbits : huffbits;
  1201. +            // Add top usebits from huffval to next usebits of nextbits
  1202. +            int tophuff = huffenc >> (huffbits - usebits);
  1203. +            next |= (tophuff << (nextbits - usebits));
  1204. +            nextbits -= usebits;
  1205. +            huffbits -= usebits;
  1206. +            huffenc &= (1 << huffbits) - 1;
  1207. +            if (nextbits == 0) {
  1208. +                out[w++] = next;
  1209. +                if (next == 0xff) out[w++] = 0x0;
  1210. +                next = 0;
  1211. +                nextbits = 8;
  1212. +            }
  1213. +        }
  1214. +        // Write the rest of the bits for the value
  1215. +        
  1216. +        while (ssss > 0) {
  1217. +            int usebits = ssss > nextbits ? nextbits : ssss;
  1218. +            // Add top usebits from huffval to next usebits of nextbits
  1219. +            int tophuff = diff >> (ssss - usebits);
  1220. +            next |= (tophuff << (nextbits - usebits));
  1221. +            nextbits -= usebits;
  1222. +            ssss -= usebits;
  1223. +            diff &= (1 << ssss) - 1;
  1224. +            if (nextbits == 0) {
  1225. +                out[w++] = next;
  1226. +                if (next == 0xff) out[w++] = 0x0;
  1227. +                next = 0;
  1228. +                nextbits = 8;
  1229. +            }
  1230. +        }
  1231. +        
  1232. +        // DPRINTF("%d %d\n",diff,ssss);
  1233. +        pixel++;
  1234. +        scan--;
  1235. +        col++;
  1236. +        if (scan == 0) {
  1237. +            pixel += self->skipLength;
  1238. +            scan = self->readLength;
  1239. +        }
  1240. +        if (col == self->width) {
  1241. +            uint16_t* tmprow = rows[1];
  1242. +            rows[1] = rows[0];
  1243. +            rows[0] = tmprow;
  1244. +            col = 0;
  1245. +            row++;
  1246. +        }
  1247. +    }
  1248. +    // Flush the final bits
  1249. +    if (nextbits < 8) {
  1250. +        out[w++] = next;
  1251. +        if (next == 0xff) out[w++] = 0x0;
  1252. +    }
  1253. +#ifdef LJ92_DEBUG
  1254. +    int sort[17];
  1255. +    for (int h = 0; h < 17; h++) {
  1256. +        sort[h] = h;
  1257. +        DPRINTF("%d:%d\n", h, self->hist[h]);
  1258. +    }
  1259. +    DPRINTF("Total bytes: %d\n", bitcount >> 3);
  1260. +#endif
  1261. +    free(rowcache);
  1262. +    self->encodedWritten = w;
  1263. +}
  1264. +
  1265. +
  1266. +/* Encoder
  1267. + * Read tile from an image and encode in one shot
  1268. + * Return the encoded data
  1269. + */
  1270. +int lj92_encode(uint16_t* image, int width, int height, int bitdepth, int components,
  1271. +                int readLength, int skipLength, uint16_t* delinearize,
  1272. +                int delinearizeLength, uint8_t** encoded, int* encodedLength) {
  1273. +    int ret = LJ92_ERROR_NONE;
  1274. +    
  1275. +    lje* self = (lje*)calloc(sizeof(lje), 1);
  1276. +    if (self == NULL) return LJ92_ERROR_NO_MEMORY;
  1277. +    self->image = image;
  1278. +    self->width = width;
  1279. +    self->height = height;
  1280. +    self->bitdepth = bitdepth;
  1281. +    self->readLength = readLength;
  1282. +    self->skipLength = skipLength;
  1283. +    self->delinearize = delinearize;
  1284. +    self->delinearizeLength = delinearizeLength;
  1285. +    self->components = components;
  1286. +    self->encodedLength = width * height * components + 200;
  1287. +    self->encoded = (uint8_t*)malloc(self->encodedLength);
  1288. +    if (self->encoded == NULL) {
  1289. +        free(self);
  1290. +        return LJ92_ERROR_NO_MEMORY;
  1291. +    }
  1292. +    // Scan through data to gather frequencies of ssss prefixes
  1293. +    ret = frequencyScan(self);
  1294. +    if (ret != LJ92_ERROR_NONE) {
  1295. +        free(self->encoded);
  1296. +        free(self);
  1297. +        return ret;
  1298. +    }
  1299. +    // Create encoded table based on frequencies
  1300. +    createEncodeTable(self);
  1301. +    // Write JPEG head and scan header
  1302. +    writeHeader(self);
  1303. +    // Scan through and do the compression
  1304. +    writeBody(self);
  1305. +    // Finish
  1306. +    writePost(self);
  1307. +#ifdef LJ92_DEBUG
  1308. +    DPRINTF("written:%d\n", self->encodedWritten);
  1309. +#endif
  1310. +    self->encoded = (uint8_t*)realloc(self->encoded, self->encodedWritten);
  1311. +    self->encodedLength = self->encodedWritten;
  1312. +    *encoded = self->encoded;
  1313. +    *encodedLength = self->encodedLength;
  1314. +    
  1315. +    free(self);
  1316. +    
  1317. +    return ret;
  1318. +}
  1319. +
  1320. diff -r a5201c4146bf -r 121d6fd2eb87 modules/mlv_rec/lj92.h
  1321. --- /dev/null   Thu Jan 01 00:00:00 1970 +0000
  1322. +++ b/modules/mlv_rec/lj92.h    Tue Apr 25 01:28:08 2017 +0200
  1323. @@ -0,0 +1,69 @@
  1324. +/*
  1325. + lj92.h
  1326. + (c) Andrew Baldwin 2014
  1327. +
  1328. + Permission is hereby granted, free of charge, to any person obtaining a copy of
  1329. + this software and associated documentation files (the "Software"), to deal in
  1330. + the Software without restriction, including without limitation the rights to
  1331. + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  1332. + of the Software, and to permit persons to whom the Software is furnished to do
  1333. + so, subject to the following conditions:
  1334. +
  1335. + The above copyright notice and this permission notice shall be included in all
  1336. + copies or substantial portions of the Software.
  1337. +
  1338. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  1339. + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  1340. + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  1341. + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  1342. + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  1343. + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  1344. + SOFTWARE.
  1345. + */
  1346. +
  1347. +#ifndef LJ92_H
  1348. +#define LJ92_H
  1349. +
  1350. +enum LJ92_ERRORS {
  1351. +    LJ92_ERROR_NONE = 0,
  1352. +    LJ92_ERROR_CORRUPT = -1,
  1353. +    LJ92_ERROR_NO_MEMORY = -2,
  1354. +    LJ92_ERROR_BAD_HANDLE = -3,
  1355. +    LJ92_ERROR_TOO_WIDE = -4
  1356. +};
  1357. +
  1358. +typedef struct _ljp* lj92;
  1359. +
  1360. +/* Parse a lossless JPEG (1992) structure returning
  1361. + * - a handle that can be used to decode the data
  1362. + * - width/height/bitdepth of the data
  1363. + * Returns status code.
  1364. + * If status == LJ92_ERROR_NONE, handle must be closed with lj92_close
  1365. + */
  1366. +int lj92_open(lj92* lj, const uint8_t* data, int datalen, int* width,
  1367. +              int* height, int* bitdepth, int* components); // Width, height and bitdepth
  1368. +
  1369. +/* Release a decoder object */
  1370. +void lj92_close(lj92 lj);
  1371. +
  1372. +/*
  1373. + * Decode previously opened lossless JPEG (1992) into a 2D tile of memory
  1374. + * Starting at target, write writeLength 16bit values, then skip 16bit skipLength value before writing again
  1375. + * If linearize is not NULL, use table at linearize to convert data values from output value to target value
  1376. + * Data is only correct if LJ92_ERROR_NONE is returned
  1377. + */
  1378. +int lj92_decode(lj92 lj,
  1379. +                uint16_t* target, int writeLength, int skipLength, // The image is written to target as a tile
  1380. +                uint16_t* linearize, int linearizeLength); // If not null, linearize the data using this table
  1381. +
  1382. +/*
  1383. + * Encode a grayscale image supplied as 16bit values within the given bitdepth
  1384. + * Read from tile in the image
  1385. + * Apply delinearization if given
  1386. + * Return the encoded lossless JPEG stream
  1387. + */
  1388. +int lj92_encode(uint16_t* image, int width, int height, int bitdepth, int components,
  1389. +                int readLength, int skipLength,
  1390. +                uint16_t* delinearize,int delinearizeLength,
  1391. +                uint8_t** encoded, int* encodedLength);
  1392. +#endif
  1393. diff -r a5201c4146bf -r 121d6fd2eb87 modules/mlv_rec/mlv_dump.c
  1394. --- a/modules/mlv_rec/mlv_dump.c    Sun Apr 23 03:09:00 2017 +0300
  1395. +++ b/modules/mlv_rec/mlv_dump.c    Tue Apr 25 01:28:08 2017 +0200
  1396. @@ -92,6 +92,10 @@
  1397.  #include <LzmaLib.h>
  1398.  #endif
  1399.  
  1400. +#ifdef MLV_USE_LJ92
  1401. +#include "lj92.h"
  1402. +#endif
  1403. +
  1404.  /* project includes */
  1405.  #include "../lv_rec/lv_rec.h"
  1406.  #include "../../src/raw.h"
  1407. @@ -626,6 +630,12 @@
  1408.                  ret = 5;
  1409.                  goto load_frame_finish;
  1410.              }
  1411. +            if(file_hdr.videoClass & MLV_VIDEO_CLASS_FLAG_LJ92)
  1412. +            {
  1413. +                print_msg(MSG_ERROR, "Compressed formats not supported for frame extraction\n");
  1414. +                ret = 5;
  1415. +                goto load_frame_finish;
  1416. +            }
  1417.          }
  1418.          else if(!memcmp(buf.blockType, "VIDF", 4))
  1419.          {
  1420. @@ -1471,6 +1481,7 @@
  1421.      {
  1422.          print_msg(MSG_INFO, "   - Enforcing 14bpp for DNG output\n");
  1423.          bit_depth = 14;
  1424. +        decompress_output = 1;
  1425.          
  1426.          /* special case - splitting into frames doesnt require a specific output file */
  1427.          if(!output_filename)
  1428. @@ -1843,6 +1854,8 @@
  1429.                  print_msg(MSG_INFO, "    File        : %d / %d\n", file_hdr.fileNum, file_hdr.fileCount);
  1430.                  print_msg(MSG_INFO, "    Frames Video: %d\n", file_hdr.videoFrameCount);
  1431.                  print_msg(MSG_INFO, "    Frames Audio: %d\n", file_hdr.audioFrameCount);
  1432. +                print_msg(MSG_INFO, "    Video class: 0x%08X\n", file_hdr.videoClass);
  1433. +                print_msg(MSG_INFO, "    Audio class: 0x%08X\n", file_hdr.audioClass);
  1434.              }
  1435.              
  1436.              if(alter_fps)
  1437. @@ -2139,8 +2152,9 @@
  1438.                      /* if already compressed, we have to decompress it first */
  1439.                      int compressed_lzma = main_header.videoClass & MLV_VIDEO_CLASS_FLAG_LZMA;
  1440.                      int compressed_lj92 = main_header.videoClass & MLV_VIDEO_CLASS_FLAG_LJ92;
  1441. -                    int recompress = compressed_lzma && compress_output;
  1442. -                    int decompress = compressed_lzma && decompress_output;
  1443. +                    int compressed = compressed_lzma || compressed_lj92;
  1444. +                    int recompress = compressed && compress_output;
  1445. +                    int decompress = compressed && decompress_output;
  1446.  
  1447.                      /* block_hdr.blockSize includes VIDF header, space (if any), actual frame, and padding (if any) */
  1448.                      /* this formula should match the one used when saving dark frames (which have no spacing/padding) */
  1449. @@ -2150,41 +2164,22 @@
  1450.                      int32_t skipSizeBefore = block_hdr.frameSpace;
  1451.                      int32_t skipSizeAfter = block_hdr.blockSize - frame_size - block_hdr.frameSpace - sizeof(mlv_vidf_hdr_t);
  1452.  
  1453. -                    if (compressed_lj92)
  1454. -                    {
  1455. -                        /* hack: ignore computed frame size and skip processing;
  1456. -                         * just read the entire block and dump it to DNG
  1457. -                         * fixme: decompression (see mlv_rec_lj92 branch)
  1458. -                         */
  1459. -                        if (verbose)
  1460. -                        {
  1461. -                            print_msg(MSG_INFO, "    LJ92: processing skipped\n");
  1462. -                        }
  1463. -                        frame_size += skipSizeAfter;
  1464. -                        skipSizeAfter = 0;
  1465. -                        fix_vert_stripes = 0;
  1466. -                        fix_cold_pixels = 0;
  1467. -                        assert(!chroma_smooth_method);
  1468. -                        assert(!subtract_mode);
  1469. -                        assert(!flatfield_mode);
  1470. -                        assert(!average_mode);
  1471. -                        assert(!bit_zap);
  1472. -                        assert(!delta_encode_mode);
  1473. -                        assert(!raw_output);
  1474. -                    }
  1475. -                    else if (skipSizeAfter < 0)
  1476. -                    {
  1477. -                        print_msg(MSG_ERROR, "VIDF: Frame size + header + space is larger than block size. Skipping\n");
  1478. -                        skip_block = 1;
  1479. -                    }
  1480.  
  1481.                      file_set_pos(in_file, skipSizeBefore, SEEK_CUR);
  1482.                      
  1483. +                    int read_size = frame_size;
  1484. +                    
  1485. +                    if (compressed_lj92)
  1486. +                    {
  1487. +                        read_size = block_hdr.blockSize - sizeof(mlv_vidf_hdr_t) - skipSizeBefore;
  1488. +                        skipSizeAfter = 0;
  1489. +                    }
  1490. +                    
  1491.                      /* check if there is enough memory for that frame */
  1492. -                    if(frame_size > (int)frame_buffer_size)
  1493. +                    if(read_size > (int)frame_buffer_size)
  1494.                      {
  1495.                          /* no, set new size */
  1496. -                        frame_buffer_size = frame_size;
  1497. +                        frame_buffer_size = read_size;
  1498.                          
  1499.                          /* realloc buffers */
  1500.                          frame_buffer = realloc(frame_buffer, frame_buffer_size);
  1501. @@ -2226,7 +2221,7 @@
  1502.                          }
  1503.                      }
  1504.                      
  1505. -                    if(fread(frame_buffer, frame_size, 1, in_file) != 1)
  1506. +                    if(fread(frame_buffer, read_size, 1, in_file) != 1)
  1507.                      {
  1508.                          print_msg(MSG_ERROR, "VIDF: File ends in the middle of a block\n");
  1509.                          goto abort;
  1510. @@ -2234,40 +2229,108 @@
  1511.  
  1512.                      file_set_pos(in_file, skipSizeAfter, SEEK_CUR);
  1513.  
  1514. -                    lua_handle_hdr_data(lua_state, buf.blockType, "_data_read", &block_hdr, sizeof(block_hdr), frame_buffer, frame_size);
  1515. -
  1516. -                    if(recompress || decompress || ((raw_output || dng_output) && compressed_lzma))
  1517. +                    lua_handle_hdr_data(lua_state, buf.blockType, "_data_read", &block_hdr, sizeof(block_hdr), frame_buffer, read_size);
  1518. +
  1519. +                    if(recompress || decompress || ((raw_output || dng_output) && compressed))
  1520.                      {
  1521. -#ifdef MLV_USE_LZMA
  1522. -                        size_t lzma_out_size = *(uint32_t *)frame_buffer;
  1523. -                        size_t lzma_in_size = frame_size - LZMA_PROPS_SIZE - 4;
  1524. -                        size_t lzma_props_size = LZMA_PROPS_SIZE;
  1525. -                        unsigned char *lzma_out = malloc(lzma_out_size);
  1526. -
  1527. -                        int ret = LzmaUncompress(
  1528. -                            lzma_out, &lzma_out_size,
  1529. -                            (unsigned char *)&frame_buffer[4 + LZMA_PROPS_SIZE], &lzma_in_size,
  1530. -                            (unsigned char *)&frame_buffer[4], lzma_props_size
  1531. -                            );
  1532. -
  1533. -                        if(ret == SZ_OK)
  1534. +                        if(compressed_lj92)
  1535.                          {
  1536. -                            frame_size = lzma_out_size;
  1537. -                            memcpy(frame_buffer, lzma_out, frame_size);
  1538. +#ifdef MLV_USE_LJ92
  1539. +                            lj92 handle;
  1540. +                            int lj92_width = 0;
  1541. +                            int lj92_height = 0;
  1542. +                            int lj92_bitdepth = 0;
  1543. +                            int lj92_components = 0;
  1544. +
  1545. +                            int ret = lj92_open(&handle, (uint8_t *)frame_buffer, read_size, &lj92_width, &lj92_height, &lj92_bitdepth, &lj92_components);
  1546. +
  1547. +                            size_t out_size = lj92_width * lj92_height * sizeof(uint16_t) * lj92_components;
  1548. +
  1549. +                            if(ret == LJ92_ERROR_NONE)
  1550. +                            {
  1551. +                                if(verbose)
  1552. +                                {
  1553. +                                    print_msg(MSG_INFO, "    LJ92: %dx%dx%d %d bpp (%d bytes buffer)\n", lj92_width, lj92_height, lj92_components, lj92_bitdepth, out_size);
  1554. +                                }
  1555. +                            }
  1556. +                            else
  1557. +                            {
  1558. +                                print_msg(MSG_INFO, "    LJ92: Failed (%d)\n", ret);
  1559. +                                goto abort;
  1560. +                            }
  1561. +                            
  1562. +                            /* we need a temporary buffer so we dont overwrite source data */
  1563. +                            uint8_t *decompressed = malloc(out_size);
  1564. +                            
  1565. +                            ret = lj92_decode(handle, decompressed, lj92_width * lj92_height * lj92_components, 0, NULL, 0);
  1566. +
  1567. +                            if(ret != LJ92_ERROR_NONE)
  1568. +                            {
  1569. +                                print_msg(MSG_INFO, "    LJ92: Failed (%d)\n", ret);
  1570. +                                goto abort;
  1571. +                            }
  1572. +                            
  1573.                              if(verbose)
  1574.                              {
  1575. -                                print_msg(MSG_INFO, "    LZMA: "FMT_SIZE" -> "FMT_SIZE"  (%2.2f%%)\n", lzma_in_size, lzma_out_size, ((float)lzma_out_size * 100.0f) / (float)lzma_in_size);
  1576. +                                print_msg(MSG_INFO, "    LJ92: "FMT_SIZE" -> "FMT_SIZE"  (%2.2f%% ratio)\n", read_size, frame_size, ((float)read_size * 100.0f) / (float)frame_size);
  1577.                              }
  1578. +                            
  1579. +                            /* repack the 16 bit words containing values with max 14 bit */
  1580. +                            int jl92_pitch = video_xRes * 16 / 8;
  1581. +                            int orig_pitch = video_xRes * lv_rec_footer.raw_info.bits_per_pixel / 8;
  1582. +
  1583. +                            for(int y = 0; y < video_yRes; y++)
  1584. +                            {
  1585. +                                void *src_line = &decompressed[y * jl92_pitch];
  1586. +                                void *dst_line = &frame_buffer[y * orig_pitch];
  1587. +
  1588. +                                for(int x = 0; x < video_xRes; x++)
  1589. +                                {
  1590. +                                    uint16_t value = bitextract(src_line, x, 16);
  1591. +
  1592. +                                    bitinsert(dst_line, x, lv_rec_footer.raw_info.bits_per_pixel, value);
  1593. +                                }
  1594. +                            }
  1595. +                            free(decompressed);
  1596. +#else
  1597. +                            print_msg(MSG_INFO, "    LJ92: not compiled into this release, aborting.\n");
  1598. +                            goto abort;
  1599. +#endif
  1600.                          }
  1601. -                        else
  1602. +                        
  1603. +                        if(compressed_lzma)
  1604.                          {
  1605. -                            print_msg(MSG_INFO, "    LZMA: Failed (%d)\n", ret);
  1606. +#ifdef MLV_USE_LZMA
  1607. +                            size_t lzma_out_size = *(uint32_t *)frame_buffer;
  1608. +                            size_t lzma_in_size = read_size - LZMA_PROPS_SIZE - 4;
  1609. +                            size_t lzma_props_size = LZMA_PROPS_SIZE;
  1610. +                            unsigned char *lzma_out = malloc(lzma_out_size);
  1611. +
  1612. +                            int ret = LzmaUncompress(
  1613. +                                lzma_out, &lzma_out_size,
  1614. +                                (unsigned char *)&frame_buffer[4 + LZMA_PROPS_SIZE], &lzma_in_size,
  1615. +                                (unsigned char *)&frame_buffer[4], lzma_props_size
  1616. +                                );
  1617. +
  1618. +                            if(ret == SZ_OK)
  1619. +                            {
  1620. +                                read_size = lzma_out_size;
  1621. +                                memcpy(frame_buffer, lzma_out, read_size);
  1622. +                                if(verbose)
  1623. +                                {
  1624. +                                    print_msg(MSG_INFO, "    LZMA: "FMT_SIZE" -> "FMT_SIZE"  (%2.2f%%)\n", lzma_in_size, lzma_out_size, ((float)lzma_out_size * 100.0f) / (float)lzma_in_size);
  1625. +                                }
  1626. +                            }
  1627. +                            else
  1628. +                            {
  1629. +                                print_msg(MSG_INFO, "    LZMA: Failed (%d)\n", ret);
  1630. +                                goto abort;
  1631. +                            }
  1632. +#else
  1633. +                            print_msg(MSG_INFO, "    LZMA: not compiled into this release, aborting.\n");
  1634.                              goto abort;
  1635. +#endif
  1636.                          }
  1637. -#else
  1638. -                        print_msg(MSG_INFO, "    LZMA: not compiled into this release, aborting.\n");
  1639. -                        goto abort;
  1640. -#endif
  1641.                      }
  1642.  
  1643.                      int old_depth = lv_rec_footer.raw_info.bits_per_pixel;
  1644. @@ -2820,7 +2883,86 @@
  1645.                          {
  1646.                              if(compress_output)
  1647.                              {
  1648. -#ifdef MLV_USE_LZMA
  1649. +#ifdef MLV_USE_LJ92_COMPRESSION
  1650. +                                uint8_t *compressed = NULL;
  1651. +                                int compressed_size = 0;
  1652. +                                int lj92_bitdepth = old_depth;
  1653. +                                
  1654. +                                /* when data is shrunk to some bpp depth, tell this the encoder */
  1655. +                                if(bit_zap)
  1656. +                                {
  1657. +                                    lj92_bitdepth = bit_zap;
  1658. +                                }
  1659. +                                
  1660. +                                /* now shift right to have used data right aligned */
  1661. +                                uint32_t shift_value = MIN(16,MAX(0, 16 - lj92_bitdepth));
  1662. +                                
  1663. +                                /* split the single channels into image tiles */
  1664. +                                uint16_t *dst_buf = malloc(video_yRes * video_xRes * sizeof(uint16_t));
  1665. +                                uint16_t *src_buf = (uint16_t *)frame_buffer;
  1666. +
  1667. +#if defined(COMPRESS_BAYER_TILES)
  1668. +                                int lj92_xres = video_xRes;
  1669. +                                int lj92_yres = video_yRes;
  1670. +
  1671. +                                for(int y = 0; y < video_yRes; y++)
  1672. +                                {
  1673. +                                    int src_y = ((2 * y) % video_yRes) + ((2 * y) / video_yRes);
  1674. +                                    
  1675. +                                    uint16_t *src_line = &src_buf[src_y * video_xRes];
  1676. +                                    uint16_t *dst_line = &dst_buf[y * video_xRes];
  1677. +
  1678. +                                    for(int x = 0; x < video_xRes; x++)
  1679. +                                    {
  1680. +                                        int src_x = ((2 * x) % video_xRes) + ((2 * x) / video_xRes);
  1681. +                                        dst_line[x] = src_line[src_x] >> shift_value;
  1682. +                                    }
  1683. +                                }
  1684. +#else
  1685. +                                /* just line up RGRGRG and GBGBGB into one pixel line */
  1686. +                                int lj92_xres = video_xRes * 2;
  1687. +                                int lj92_yres = video_yRes / 2;
  1688. +
  1689. +                                for(int y = 0; y < video_yRes; y++)
  1690. +                                {
  1691. +                                    uint16_t *src_line = &src_buf[y * video_xRes];
  1692. +                                    uint16_t *dst_line = &dst_buf[y * video_xRes];
  1693. +
  1694. +                                    for(int x = 0; x < video_xRes; x++)
  1695. +                                    {
  1696. +                                        dst_line[x] = src_line[x] >> shift_value;
  1697. +                                    }
  1698. +                                }
  1699. +#endif
  1700. +                                
  1701. +                                int ret = lj92_encode(dst_buf, lj92_xres, lj92_yres, lj92_bitdepth, 4, lj92_xres * lj92_yres, 0, NULL, 0, &compressed, &compressed_size);
  1702. +                                free(dst_buf);
  1703. +
  1704. +                                if(ret == LJ92_ERROR_NONE)
  1705. +                                {
  1706. +                                    if(verbose)
  1707. +                                    {
  1708. +                                        print_msg(MSG_INFO, "    LJ92: "FMT_SIZE" -> "FMT_SIZE"  (%2.2f%%) %dx%d %d bpp\n", frame_size, compressed_size, ((float)compressed_size * 100.0f) / (float)frame_size, lj92_xres, lj92_yres, lj92_bitdepth);
  1709. +                                    }
  1710. +                                    
  1711. +                                    /* store original frame size */
  1712. +                                    *(uint32_t *)frame_buffer = frame_size;
  1713. +                                    
  1714. +                                    /* set new compressed size and copy buffers */
  1715. +                                    frame_size = compressed_size + 4;
  1716. +                                    memcpy(&frame_buffer[4], compressed, compressed_size);
  1717. +                                    
  1718. +                                }
  1719. +                                else
  1720. +                                {
  1721. +                                    print_msg(MSG_INFO, "    LJ92: Failed (%d)\n", ret);
  1722. +                                    goto abort;
  1723. +                                }
  1724. +                                
  1725. +                                free(compressed);
  1726. +
  1727. +#elif defined(MLV_USE_LZMA_COMPRESSION)
  1728. +
  1729.                                  size_t lzma_out_size = 2 * frame_size;
  1730.                                  size_t lzma_in_size = frame_size;
  1731.                                  size_t lzma_props_size = LZMA_PROPS_SIZE;
  1732. @@ -2854,7 +2996,7 @@
  1733.                                  }
  1734.                                  free(lzma_out);
  1735.  #else
  1736. -                                print_msg(MSG_INFO, "    LZMA: not compiled into this release, aborting.\n");
  1737. +                                print_msg(MSG_INFO, "    no compression type compiled into this release, aborting.\n");
  1738.                                  goto abort;
  1739.  #endif
  1740.                              }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×