Advertisement
Guest User

Untitled

a guest
Apr 24th, 2017
284
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 60.60 KB | None | 0 0
  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.                              }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement