Advertisement
Guest User

Untitled

a guest
Apr 10th, 2018
443
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 33.98 KB | None | 0 0
  1.  
  2. //  Для dxdy, 10 апреля 2018 г.
  3. // Файл "jpg_opt.c"
  4. // Аргументом указать имя входного JPEG-файла. После работы программы
  5. // должен получиться оптимизированный файл "test.jpg".
  6.  
  7. //   gcc jpg_opt.c -o jpg_opt.cgi -Wall -Werror -O3
  8. //   ./jpg_opt.cgi
  9.  
  10.  
  11. /***************************************************
  12. * Функция оптимизации кодов Хаффмана в JPEG-файле.
  13. * Для JPEG-файлов, закодированных базовым способом (baseline).
  14. *
  15. * int fjp_opt_hfm(const char *in_buf, int len_in_buf, FILE *fp,
  16. *                 int *w, int *h, int *err)
  17. *
  18. * in_buf     -входной буфер содержит JPEG-файл;
  19. * len_in_buf -длина данных во входном буфере;
  20. * fp   -выходной файл;
  21. * w, h -ширина и высота;
  22. * err  -возврат ошибки, можно NULL.
  23. *
  24. * Возврат: длина выходного файла или -1.
  25. * Для распечатки ошибок есть функция
  26. * const char *fjp_strerror(int err)
  27. * **************************************************/
  28.  
  29. #include <stdio.h>
  30. #include <string.h>
  31. #include <stdlib.h>
  32. #include <limits.h>
  33.  
  34. #define FJP_FL_TEST   1 // 0 -тестовая распечатка выключена, 1 -включена
  35.  
  36. // макросы ошибок
  37. #define FJP_ERR_RD_FILE       1
  38. #define FJP_ERR_SYNTAX        2
  39. #define FJP_ERR_NOT_SUPPORT   3
  40. #define FJP_ERR_MEMORY        4
  41. #define FJP_ERR_DECODE        5
  42. #define FJP_ERR_INVAL         6
  43. #define FJP_ERR_WR_FILE       7
  44.  
  45. // отладочные глобальные переменные
  46. int n1_FF = 0; // счетчик байтов 0xFF в скане входного файла
  47. int n2_FF = 0; // счетчик байтов 0xFF в скане выходного файла
  48. int d1_C4 = 0; // длина таблиц Хаффмана во входном файле
  49. int d2_C4 = 0; // длина таблиц Хаффмана в выходном файле
  50. int b1_DA = 0; // начало скана во входном файле
  51. int e1_DA = 0; // конец скана во входном файле
  52. int b2_DA = 0; // начало скана в выходном файле
  53. int e2_DA = 0; // конец скана в выходном файле
  54. int fl = 0; // для функции оптимизации, для максимальной длины кодов
  55. int maxlen = 0; // максимальная длина кода до уменьшения
  56.  
  57. //--- таблицы Хаффмана (кодирование) ---
  58. // вынесены в отдельную структуру, чтоб не обнулялись
  59. // на второй проход.
  60.  
  61. // структура для построения дерева Хаффмана
  62. struct s_fjp_tree {
  63.     unsigned int a[257];
  64.     unsigned int b[257];
  65.     int pa[257];
  66.     int pp[257];
  67.     int p[257];
  68.     int bl_count[257];
  69. };
  70.  
  71. // структура кодов Хаффмана
  72. struct s_fjp_sym {
  73.     unsigned int   freq; // частота символа
  74.     int   hcod; // код Хаффмана
  75.     int   bits; // длина кода Хаффмана
  76. };
  77.  
  78. // обобщенная структура для кодирования Хаффмана
  79. struct s_fjp1 {
  80.     struct s_fjp_tree  tree[1];
  81.  
  82.     struct {
  83.         struct s_fjp_sym sym[256];
  84.         int n;
  85.         char buf[16+256]; // таблицы для файла JPEG
  86.     } fsym[8];
  87. };
  88.  
  89. //--- обобщенная структура ---
  90. struct s_fjp {
  91.     const char  *p0; // начало входного буфера
  92.     const char  *p1; // текущая позиция входного буфера
  93.     const char  *p2; // за край данных входного буфера
  94.  
  95.     char  buf_C4[2048]; // буфер для подменных таблиц Хаффмана
  96.  
  97.     char  buf[8192]; // вспомогательный буфер
  98.     int   rstN;      // число макроблоков рестарта
  99.     int   rstn;      // счетчик макроблоков рестарта
  100.     int   nextrst;   // счетчик циклов рестарта
  101.  
  102.     int idcomp[4];   // идентификаторы компрнентов
  103.     int dchfm[4];    // номера DC-таблиц Хаффмана в массиве shfm
  104.     int achfm[4];    // номера AC-таблиц Хаффмана в массиве shfm
  105.  
  106.     int   w;         // ширина
  107.     int   h;         // высота
  108.     int   ncomp;     // число компонентов
  109.     int   fl_start;  // счетчик сканов
  110.  
  111.     int   xblok;     // x -размер макроблока в пикселях
  112.     int   yblok;     // y -размер макроблока в пикселях
  113.     int   xm;        // ширина рисунка в макроблоках (с краевыми)
  114.     int   ym;        // высота рисунка в макроблоках (с краевыми)
  115.     int   nblok;     // общее число макроблоков
  116.  
  117.     int   bit_count;   // счетчик битов (декодирование)
  118.     unsigned long ch;  // буфер битов   (декодирование)
  119.     int   bit_count2;  // счетчик битов (кодирование)
  120.     unsigned long ch2; // буфер битов   (кодирование)
  121.     int   err;
  122.  
  123.     //--- структура компонентов ---
  124.     struct{
  125.         int dchfm;  // DC-таблица Хаффмана в массиве shfm (ниже)
  126.         int achfm;  // AC-таблица Хаффмана в массиве shfm (ниже)
  127.  
  128.         int nx; // число матриц на макроблок в ширину
  129.         int ny; // число матриц на макроблок в высоту
  130.         int n;  // число матриц на макроблок
  131.     } comp[4];
  132.  
  133.     //--- таблицы Хаффмана (декодирование) ---
  134.     struct{
  135.         char sym[256]; // список символов в порядке возрастания кода
  136.         int n;         // число символов
  137.         int max[17];   // Все коды длины len меньше max[len]
  138.         int idx[17];   // Если код Хаффмана прибавить к элементу этого массива
  139.                        // для соответствующей длины кода, то получится индекс
  140.                        // массива sym, по которому лежит нужный символ
  141.                        // i = idx[len] + cod; symbol = sym[i];
  142.     } shfm[8];
  143.  
  144.     struct s_fjp1  *s1; // структура вынесена, чтоб не обнулялась вместе с этой
  145.     int fl;             // 0 -первый проход; 1 -второй
  146.     FILE *fp;           // выходной файл
  147.     int sizefile;       // длина файла
  148. };
  149.  
  150.  
  151. //-------------- fjp_hfm_code --------------------
  152. // расчет кодов Хаффмана
  153. // buf -сюда заряжает таблицу кодов для файла JPEG
  154. int fjp_hfm_code(struct s_fjp_tree *tree, struct s_fjp_sym *sym, char *buf)
  155. {
  156.     int i, j, k, n, cod, bits, len;
  157.     unsigned int t, aa, ab, bb;
  158.     unsigned int *a  = tree->a;  // частоты листьев
  159.     unsigned int *b  = tree->b;  // частоты узлов
  160.     int *pa = tree->pa; // родительский узел листа
  161.     int *pp = tree->pp; // родительский узел узла
  162.     int *p  = tree->p;  // номер символа, его значение
  163.     int *bl_count = tree->bl_count; // счетчики числа кодов для разных длин
  164.  
  165.     // зарядка исходных массивов (a[0] -подставной символ)
  166.     memset(tree, 0, sizeof(struct s_fjp_tree));
  167.     for(a[0]=1, i=0, n=1; i < 256; i++){
  168.         if(sym[i].freq > 0){
  169.             a[n]   = sym[i].freq;
  170.             p[n++] = i;
  171.         }
  172.     }
  173.     memset(buf, 0, 16+n-1);
  174.     if(n==1) return(0); // n -число используемых символов алфавита + 1
  175.     if(n==2){ bl_count[1] += 2; goto RET;}
  176.  
  177.     // сортировка по возрастанию частоты символов
  178.     for(i=1; i<n; i++){
  179.         for(j=n-1; j>i; j--){
  180.             if(a[j] < a[j-1]){
  181.                 t = a[j]; a[j] = a[j-1]; a[j-1] = t;
  182.                 t = p[j]; p[j] = p[j-1]; p[j-1] = t;
  183.             }
  184.         }
  185.     }
  186.  
  187.     // создание дерева
  188.     for(k=0, i=0, j=0; k<(n-1); k++){
  189.         if(i<(n-1))    aa = a[i] + a[i+1]; else aa = UINT_MAX;
  190.         if(i<n && j<k) ab = a[i] + b[j];   else ab = UINT_MAX;
  191.         if(j<(k-1))    bb = b[j] + b[j+1]; else bb = UINT_MAX;
  192.  
  193.         if(aa <= ab && aa <= bb){
  194.             b[k] = aa;
  195.             pa[i++] = k; pa[i++] = k; // родительский узел
  196.         }
  197.         else if(ab <= aa && ab <= bb){
  198.             b[k] = ab;
  199.             pa[i++] = k; pp[j++] = k; // родительский узел
  200.         }
  201.         else{
  202.             b[k] = bb;
  203.             pp[j++] = k; pp[j++] = k; // родительский узел
  204.         }
  205.     }
  206.  
  207.     // обход дерева
  208.     for(--k, i=0; i<n; i++){ // k -индекс корневого узла
  209.         for(len=1, j=pa[i]; j<k; j=pp[j], len++);
  210.         bl_count[len]++;
  211.     }
  212.  
  213.     // уменьшение длин кодов
  214.     for(i=n-1; i>16; i--){
  215.         for(; bl_count[i]>0;){
  216.  
  217.             if(fl==0){ //-------------------------------отладочная-------
  218.                 maxlen = i;
  219.                 fl=1;
  220.             }
  221.  
  222.             for(j=i-2; j>0 && bl_count[j]<=0; j--);
  223.             bl_count[i] -= 2;
  224.             bl_count[i-1]++;
  225.             bl_count[j]--;
  226.             bl_count[j+1] += 2;
  227.         }
  228.     }
  229.  
  230. RET:
  231.  
  232.     // зарядка выходного массива
  233.     for(k=16; k>0 && bl_count[k]==0; k--);
  234.     bl_count[k]--; // удаление подставного символа
  235.     for(i=1; i<=16; i++) *buf++ = bl_count[i];
  236.     for(cod=0, i=n-1, bits=1; bits <= k; bits++){
  237.         for(j=0; j < bl_count[bits]; j++){
  238.             *buf++ = t = p[i--];
  239.             sym[t].bits = bits;
  240.             sym[t].hcod = cod++;
  241.         }
  242.         cod = cod << 1;
  243.     }
  244.     return(n-1);
  245. }
  246.  
  247. //------------------ fjp_init_struct --------------------------
  248.  
  249. void fjp_init_struct(struct s_fjp *s, const char *in_buf, int len_in_buf,
  250.                      struct s_fjp1 *s1, FILE *fp)
  251. {
  252.     int i;
  253.  
  254.     memset(s, 0, sizeof(struct s_fjp));
  255.     s->p0 = in_buf;
  256.     s->p1 = in_buf;
  257.     s->p2 = in_buf + len_in_buf;
  258.     s->s1 = s1;
  259.     s->fp = fp;
  260.     for(i=0; i<4; i++) s->dchfm[i] = -1;
  261.     for(i=0; i<4; i++) s->achfm[i] = -1;
  262.     return;
  263. }
  264.  
  265.  
  266. //------------- fjp_putc_fp -----------
  267.  
  268. int fjp_putc_fp(int ch, struct s_fjp *s)
  269. {
  270.     int k;
  271.     k = fputc(ch, s->fp);
  272.     if(k < 0){ s->err = FJP_ERR_WR_FILE; return(-1);}
  273.     s->sizefile++;
  274.     return(k);
  275. }
  276.  
  277. //----------------- fjp_fwrite_fp ------------
  278.  
  279. int fjp_fwrite_fp(const char *buf, int Selem, int n, struct s_fjp *s)
  280. {
  281.     int k;
  282.     k = fwrite(buf, Selem, n, s->fp);
  283.     if(k != n){ s->err = FJP_ERR_WR_FILE; return(-1);}
  284.     s->sizefile += (Selem * n);
  285.     return(n);
  286. }
  287.  
  288. //------------------- fjp_put_bits -------------------
  289. // положить в выходной поток bits бит.
  290. int fjp_put_bits(int cod, int bits, struct s_fjp *s)
  291. {
  292.     int val;
  293.  
  294.     s->ch2 = (s->ch2 << bits) + (((1 << bits) - 1) & cod);
  295.     s->bit_count2 += bits;
  296.     while(s->bit_count2 >= 8){
  297.         s->bit_count2 -= 8;
  298.         val=(s->ch2 >> s->bit_count2) & 255;
  299.         if(fjp_putc_fp(val, s) < 0) return(-1);
  300.         if(val==0xFF){
  301.             if(fjp_putc_fp(0, s) < 0) return(-1);
  302.  
  303.             n2_FF++; //------------------------------------отладочная-----
  304.  
  305.         }
  306.     }
  307.     return(0);
  308. }
  309.  
  310. //--------------- fjp_flush_bits --------------
  311. // сбросить в выходной поток оставшиеся биты
  312. int fjp_flush_bits(struct s_fjp *s)
  313. {
  314.     int val, bits;
  315.  
  316.     bits = s->bit_count2;
  317.     if(bits > 0){
  318.         val = ((s->ch2 << (8-bits)) | ((1 << (8-bits)) - 1)) & 255;
  319.         if(fjp_putc_fp(val, s) < 0) return(-1);
  320.         if(val==0xFF){
  321.             if(fjp_putc_fp(0, s) < 0) return(-1);
  322.  
  323.             n2_FF++; //------------------------------------отладочная-----
  324.  
  325.         }
  326.     }
  327.     s->bit_count2 = s->ch2 = 0;
  328.     return(0);
  329. }
  330.  
  331. //-------------- fjp_fgetc_buf ------------
  332. // подобна fgetc
  333. int fjp_fgetc_buf(struct s_fjp *s)
  334. {
  335.     if(s->p1 >= s->p2){ s->err = FJP_ERR_RD_FILE; return(-1);}
  336.     return((*s->p1++)&255);
  337. }
  338.  
  339. //------------------ fjp_fread_buf -----------------------
  340. // подобна fread
  341. int fjp_fread_buf(char *buf, int Selem, int n, struct s_fjp *s)
  342. {
  343.     int len;
  344.     if(Selem<0 || n<0) return(0);
  345.     if(Selem==0 || n==0) return(n);
  346.     len = Selem * n;
  347.     if(len > (s->p2 - s->p1)){ s->err = FJP_ERR_RD_FILE; return(-1);}
  348.     memmove(buf, s->p1, len);
  349.     s->p1 += len;
  350.     return(n);
  351. }
  352.  
  353. //------------------ fjp_get_n_bit --------------------
  354. // взять n бит
  355. int fjp_get_n_bits(struct s_fjp *s, int n)
  356. {
  357.     int k, k1;
  358.  
  359.     while(s->bit_count < n){
  360.         k=fjp_fgetc_buf(s);
  361.         if(k<0) return(-1);
  362.         if(k == 0xFF){
  363.             k1=fjp_fgetc_buf(s);
  364.             if(k1 < 0) return(-1);
  365.             if(k1 != 0){ s->err = FJP_ERR_DECODE; return(-1);}
  366.  
  367.             n1_FF++; //------------------------------------отладочная-----
  368.  
  369.         }
  370.         s->ch = (s->ch << 8) | k;
  371.         s->bit_count += 8;
  372.     }
  373.     s->bit_count -= n;
  374.     k = (s->ch >> s->bit_count)&((1 << n) - 1);
  375.     return(k);
  376. }
  377.  
  378. //-------------------- fjp_make_h_tree -----------------------
  379. // построение таблицы Хаффмана. id -номер таблицы Хаффмана
  380. int fjp_make_h_tree(const char *buf, int Lbuf, struct s_fjp *s, int id)
  381. {
  382.     int i, k, n, cod, len;
  383.  
  384.     if(Lbuf < 16){ s->err = FJP_ERR_SYNTAX; return(-1);}
  385.     for(i=0, n=0; i<16; i++) n = n + (buf[i]&255); // подсчёт символов
  386.     if(n==0 || n>256 || (n+16)>Lbuf){ s->err = FJP_ERR_SYNTAX; return(-1);}
  387.  
  388.     memset(&s->shfm[id], 0, sizeof(s->shfm[0]));
  389.     memmove(s->shfm[id].sym, buf + 16, n); // символы
  390.     s->shfm[id].n = n;
  391.  
  392.     for(len = 1, cod = 0, i=0; len <= 16; len++){
  393.         k = buf[len-1] & 255; // число кодов текущей длины
  394.         if(k > 0){
  395.             s->shfm[id].idx[len] = i - cod;
  396.             i += k;
  397.             cod += k;
  398.             if(cod > ((1 << len) - 1)){ s->err = FJP_ERR_SYNTAX; return(-1);}
  399.             s->shfm[id].max[len] = cod; // максимальный код текущей длины + 1
  400.         }
  401.         cod <<= 1;
  402.     }
  403.     return(n);
  404. }
  405.  
  406. //------------------ fjp_get_h_cod --------------------
  407. // взять код Хаффмана. id -номер таблцы Хаффмана
  408. int fjp_get_h_cod(struct s_fjp *s, int id)
  409. {
  410.     int *max, cod, len, k, k1;
  411.  
  412.     max = s->shfm[id].max; // массив максимальных кодов для разных длин
  413.     for(cod=0, len=1; len<=16; len++){
  414.         if(s->bit_count <= 0){
  415.             k = fjp_fgetc_buf(s);
  416.             if(k < 0) return(-1);
  417.             if(k == 0xFF){
  418.                 k1=fjp_fgetc_buf(s);
  419.                 if(k1 < 0) return(-1);
  420.                 if(k1 != 0){ s->err = FJP_ERR_DECODE; return(-1);}
  421.  
  422.                 n1_FF++; //--------------------------------отладочная-----
  423.  
  424.             }
  425.             s->ch = k;
  426.             s->bit_count = 8;
  427.         }
  428.         s->bit_count--;
  429.         cod = cod << 1;
  430.         if((s->ch & (1 << s->bit_count)) != 0) cod = cod | 1;
  431.         if(cod < max[len]){
  432.             k = s->shfm[id].idx[len] + cod;
  433.             return(s->shfm[id].sym[k] & 255);
  434.         }
  435.     }
  436.     s->err = FJP_ERR_DECODE;
  437.     return(-1);
  438. }
  439.  
  440. //--------------- fjp_get_cod --------------------
  441. // взять код Хаффмана и значение коэффициента
  442. int fjp_get_cod(struct s_fjp *s, int id)
  443. {
  444.     int hcod, bits, k;
  445.     struct s_fjp_sym  *sym = s->s1->fsym[id].sym;
  446.  
  447.     hcod = k = fjp_get_h_cod(s, id);
  448.     if(k < 0) return(-1);
  449.     if(s->fl > 0){
  450.         if(fjp_put_bits(sym[k].hcod, sym[k].bits, s) < 0) return(-1);
  451.     }
  452.     else sym[k].freq++;
  453.     bits = k & 15;
  454.     if(bits==0) return(hcod);
  455.     k = fjp_get_n_bits(s, bits);
  456.     if(k < 0) return(-1);
  457.     if(s->fl > 0){
  458.         if(fjp_put_bits(k, bits, s) < 0) return(-1);
  459.     }
  460.     return(hcod);
  461. }
  462.  
  463. //------------- fjp_get_matric ---------------
  464. // Взять матрицу базового JPEG
  465. int fjp_get_matric(struct s_fjp *s, int comp)
  466. {
  467.     int hcod, ft, id;
  468.  
  469.     id = s->comp[comp].dchfm;  // номер DC-таблицы Хаффмана
  470.     hcod = fjp_get_cod(s, id); // получаем DC-diff
  471.     if(hcod<0) return(-1);
  472.  
  473.     id = s->comp[comp].achfm;   // номер AC-таблицы Хаффмана
  474.     ft = 1;
  475.     while(ft <= 63){
  476.         hcod = fjp_get_cod(s, id);
  477.         if(hcod<0) return(-1);
  478.         if((hcod & 0x0F)==0){
  479.             if(hcod == 0x00) break;
  480.             if(hcod == 0xF0){ ft += 16; continue;}
  481.             s->err = FJP_ERR_DECODE; return(-1);
  482.         }
  483.         else ft += (hcod >> 4);
  484.         ft++;
  485.     }
  486.     return(0);
  487. }
  488.  
  489. //------------ fjp_make_rst -----------
  490. // обработка рестарта
  491. int fjp_make_rst(struct s_fjp *s)
  492. {
  493.     int k;
  494.  
  495.     k=fjp_fgetc_buf(s);
  496.     if(k<0) return(-1);
  497.     if(k!=0xFF){ s->err = FJP_ERR_DECODE; return(-1);}
  498.     k=fjp_fgetc_buf(s);
  499.     if(k<0) return(-1);
  500.     if(((k & 0xF8)!=0xD0)||((k&7)!=s->nextrst)){
  501.         s->err = FJP_ERR_DECODE; return(-1);
  502.     }
  503.     s->nextrst = (s->nextrst + 1) & 7;
  504.     s->rstn = 0;
  505.     s->bit_count = 0;
  506.     s->ch = 0;
  507.     if(s->fl > 0){
  508.         if(fjp_flush_bits(s) < 0) return(-1);
  509.         if(fjp_putc_fp(0xFF, s) < 0) return(-1);
  510.         if(fjp_putc_fp(k, s) < 0) return(-1);
  511.     }
  512.     return(0);
  513. }
  514.  
  515. //------------- fjp_get_blok_base -------------
  516. // взять макроблок базового JPEG-файла
  517. int fjp_get_blok_base(struct s_fjp *s)
  518. {
  519.     int comp, k, n;
  520.  
  521.     for(comp=0; comp < s->ncomp; comp++){
  522.         for(n=0; n < s->comp[comp].n; n++){
  523.             k = fjp_get_matric(s, comp);
  524.             if(k<0) return(-1);
  525.         }
  526.     }
  527.     return(0);
  528. }
  529.  
  530. //------------- fjp_get_scan_base ---------------
  531. // взять скан базового JPEG-файла
  532. int fjp_get_scan_base(struct s_fjp *s)
  533. {
  534.     int x, y, xm, ym;
  535.  
  536.     xm = s->xm;    // ширина рисунка в макроблоках
  537.     ym = s->ym;    // высота рисунка в макроблоках
  538.     for(y=0; y<ym; y++){
  539.         for(x=0; x<xm; x++){
  540.             if(s->rstN > 0){ // обработка рестарта
  541.                 if(s->rstn >= s->rstN){
  542.                     if(fjp_make_rst(s) < 0) return(-1);
  543.                 }
  544.                 s->rstn++;
  545.             }
  546.             if(fjp_get_blok_base(s) < 0) return(-1);
  547.         }
  548.     }
  549.     if(s->fl > 0){ if(fjp_flush_bits(s) < 0) return(-1);}
  550.     return(0);
  551. }
  552.  
  553. //---------------- fjp_get_marker -----------------
  554. // взять маркер
  555. int fjp_get_marker(struct s_fjp *s)
  556. {
  557.     int k;
  558.     k=fjp_fgetc_buf(s); if(k<0)  return(-1);
  559.     if(k != 0xFF){ s->err = FJP_ERR_SYNTAX;  return(-1);}
  560.     k=fjp_fgetc_buf(s); if(k<0)  return(-1);
  561.     return(k);
  562. }
  563.  
  564. //---------------- fjp_get_2_byte -----------------
  565. // взять два байта
  566. int fjp_get_2_byte(struct s_fjp *s)
  567. {
  568.     int k, n;
  569.     k=fjp_fgetc_buf(s); if(k<0)  return(-1);
  570.     k=k<<8;
  571.     n=fjp_fgetc_buf(s); if(n<0)  return(-1);
  572.     return(k+n);
  573. }
  574.  
  575. //------------- fjp_get_segment -----------------
  576. // взять сегмент в буфер
  577. int fjp_get_segment(char *buf, int Sbuf, struct s_fjp *s)
  578. {
  579.     int k;
  580.     k=fjp_get_2_byte(s); if(k<0) return(-1);
  581.     k=k-2;
  582.     if(k<=0) return(0);
  583.     if(k > Sbuf){ s->err = FJP_ERR_SYNTAX;  return(-1);}
  584.     if(fjp_fread_buf(buf, k, 1, s) < 0) return(-1);
  585.     return(k);
  586. }
  587.  
  588. //----------------- fjp_rol_segment ---------------
  589. // пропустить сегмент
  590. int fjp_rol_segment(char *buf, int Sbuf, struct s_fjp *s)
  591. {
  592.     int k, n, m, dl;
  593.  
  594.     dl=fjp_get_2_byte(s); if(dl<0) return(-1);
  595.     dl -= 2; if(dl<=0) return(0);
  596.     k=dl;
  597.     if(s->fl > 0){
  598.         if(fjp_putc_fp((dl+2) >> 8, s) < 0) return(-1);
  599.         if(fjp_putc_fp(dl+2, s) < 0) return(-1);;
  600.     }
  601.     while(k>0){
  602.         if(k>Sbuf) n=Sbuf;
  603.         else n=k;
  604.         m=fjp_fread_buf(buf, n, 1, s); if(m<0) return(-1);
  605.         k=k-n;
  606.         if(s->fl > 0){
  607.             if(fjp_fwrite_fp(buf, n, 1, s) < 0) return(-1);
  608.         }
  609.     }
  610.     return(dl);
  611. }
  612.  
  613. //--------------------- fjp_decode_DD -------------
  614. // установка рестарта
  615. int fjp_decode_DD(struct s_fjp *s, char *buf, int Lbuf)
  616. {
  617.     if(Lbuf != 2){ s->err = FJP_ERR_SYNTAX;  return(-1);}
  618.     s->rstN = ((buf[0]&255)<<8)+ (buf[1]&255);
  619.     return(0);
  620. }
  621.  
  622. //---------------- fjp_decode_C4 -----------------------
  623. // взять таблицы Хаффмана
  624. int fjp_decode_C4(struct s_fjp *s, char *buf, int Lbuf)
  625. {
  626.     int k, k1, k2, i, id, ch, dl=0, dl0;
  627.     char *v1 = s->buf_C4;
  628.  
  629.     for(i=0; (i+17) < Lbuf; i += (k+17)){
  630.         ch = buf[i]&255;
  631.         k1 = (ch >> 4) & 15; // 0 -DC, 1 -AC-коэффициенты
  632.         k2 = ch & 15;        // идентификатор таблицы
  633.         if(k1>1 || k2>3){ s->err = FJP_ERR_SYNTAX; return(-1);}
  634.         if(k1==0){ s->dchfm[k2] = id = k2;}
  635.         else{ s->achfm[k2] = id = k2 + 4;}
  636.         k = fjp_make_h_tree(buf+i+1, Lbuf-1-i, s, id);
  637.         if(k<0) return(-1);
  638.  
  639.         if(s->fl > 0){
  640.             dl0 = s->s1->fsym[id].n + 16;
  641.             dl = dl + dl0 + 1;
  642.  
  643. #if FJP_FL_TEST > 0
  644.             printf("T4: dl1=%3d; dl2=%3d; n1=%3d; n2=%3d; %s[%d]\n",
  645.                    Lbuf, dl, k, s->s1->fsym[id].n, k1==0 ? "DC":"AC", k2);
  646. #endif
  647.  
  648.             if(dl > (int)sizeof(s->buf_C4)){
  649.                 s->err = FJP_ERR_SYNTAX; return(-1);
  650.             }
  651.             *v1++ = ch;
  652.             memmove(v1, s->s1->fsym[id].buf, dl0);
  653.             v1 += dl0;
  654.         }
  655.     }
  656.  
  657.     d1_C4 = d1_C4 + Lbuf; //-------------------------------отладочная------
  658.     d2_C4 = d2_C4 + dl;
  659.  
  660.     if(s->fl > 0){
  661.         if(fjp_putc_fp(((dl+2)>>8)&255, s) < 0) return(-1);
  662.         if(fjp_putc_fp(((dl+2)&255), s) < 0) return(-1);
  663.         if(fjp_fwrite_fp(s->buf_C4, dl, 1, s) < 0) return(-1);
  664.     }
  665.     return(0);
  666. }
  667.  
  668. //---------------- fjp_decode_C0 -----------------------
  669. // ширина, высота, прореживание, id таблиц квантования
  670. int fjp_decode_C0(struct s_fjp *s, const char *buf, int Lbuf)
  671. {
  672.     int k, i, comp;
  673.     int nx=0, ny=0;
  674.     int nxmax=0, nymax=0;
  675.  
  676.     if(Lbuf<9){ s->err = FJP_ERR_SYNTAX; return(-1);}
  677.  
  678.     s->h = ((buf[1]&255)<<8)+(buf[2]&255);
  679.     s->w = ((buf[3]&255)<<8)+(buf[4]&255);
  680.     if(buf[0]!=8 || s->w < 1 || s->w > 32767 || s->h < 1 || s->h > 32767 ||
  681.         (INT_MAX / 4 / (int)sizeof(int) / s->w) < s->h)
  682.     {
  683.         s->err = FJP_ERR_NOT_SUPPORT; return(-1);
  684.     }
  685.     k = buf[5] & 255; // число компонент в рисунке
  686.     if(k!=1 && k!=3 && k!=4){ s->err = FJP_ERR_NOT_SUPPORT; return(-1);}
  687.     if(Lbuf<(6 + k * 3)){ s->err = FJP_ERR_SYNTAX; return(-1);}
  688.     s->ncomp = k; // число компонент в рисунке
  689.     for(comp=0, i=6; comp < s->ncomp; comp++){
  690.         s->idcomp[comp] = buf[i++] & 255; // идентификатор компонента
  691.         k = buf[i++] & 255; // индикатор прореживания
  692.         nx = (k >> 4);
  693.         ny = k & 15;
  694.         if(nx!=1 && nx!=2){ s->err = FJP_ERR_NOT_SUPPORT; return(-1);}
  695.         if(ny!=1 && ny!=2){ s->err = FJP_ERR_NOT_SUPPORT; return(-1);}
  696.         s->comp[comp].nx = nx; // размер макроблока в матрицах по x
  697.         s->comp[comp].ny = ny; // размер макроблока в матрицах по y
  698.         s->comp[comp].n  = nx * ny; // всего матриц в одном макроблоке
  699.         if(nxmax < nx) nxmax = nx;
  700.         if(nymax < ny) nymax = ny;
  701.         k = buf[i++] & 255; // Идентификатор таблицы квантования
  702.     }
  703.     s->xblok = nxmax<<3; // пикселей на макроблок по x
  704.     s->yblok = nymax<<3; // пикселей на макроблок по y
  705.     s->xm = (s->w + s->xblok - 1)/s->xblok;   // ширина рисунка в макроблоках
  706.     s->ym = (s->h + s->yblok - 1)/s->yblok;   // высота рисунка в макроблоках
  707.     s->nblok = s->xm * s->ym;                 // размер рисунка в макроблоках
  708.     return(0);
  709. }
  710.  
  711. //---------------- fjp_decode_DA -----------------------
  712. // графика
  713. int fjp_decode_DA(struct s_fjp *s, const char  *buf, int Lbuf)
  714. {
  715.     int k, n, k1, k2, comp=0, ncomp, idcomp;
  716.     const char *p1;
  717.  
  718.     if(Lbuf<6){ s->err = FJP_ERR_SYNTAX; return(-1);}
  719.     p1=buf;
  720.     k=(*p1++)&255; // число компонент в этом скане
  721.     if((k!=1 && k!=3 && k!=4) || k > s->ncomp || Lbuf < (4 + k*2)){
  722.         s->err = FJP_ERR_SYNTAX; return(-1);
  723.     }
  724.     ncomp = k; // число компонент в этом скане
  725.  
  726.     // обнуляем
  727.     s->bit_count = 0;
  728.     s->ch = 0;
  729.     s->rstn = s->nextrst = 0;
  730.     for(n=0; n<ncomp; n++){
  731.         idcomp = (*p1++)&255; // идентификатор компонента
  732.         for(k=0; k < s->ncomp; k++){ if(s->idcomp[k] == idcomp) break;}
  733.         if(k >= s->ncomp){ s->err = FJP_ERR_SYNTAX; return(-1);}
  734.         comp = k;
  735.  
  736.         k=(*p1++)&255;
  737.         k1=(k>>4)&15; // Идентификатор таблицы Хаффмана для DC
  738.         k2=k&15;      // Идентификатор таблицы Хаффмана для AC
  739.         if(k1>3 || k2>3){ s->err = FJP_ERR_NOT_SUPPORT; return(-1);}
  740.  
  741.         s->comp[comp].dchfm = s->dchfm[k1];
  742.         s->comp[comp].achfm = s->achfm[k2];
  743.         // проверяем наличие таблиц Хаффмана
  744.         if(s->comp[comp].dchfm < 0 || s->comp[comp].achfm < 0){
  745.             s->err = FJP_ERR_SYNTAX; return(-1);
  746.         }
  747.     }
  748.     if(*p1!=0 || *(p1+1)!=63 || *(p1+2)!=0){
  749.         s->err = FJP_ERR_SYNTAX; return(-1);
  750.     }
  751.  
  752.     b1_DA = (int)(s->p1 - s->p0); //----------------------отладочная------
  753.     b2_DA = s->sizefile;
  754.  
  755.     k=fjp_get_scan_base(s);  // базовый
  756.  
  757.     e1_DA = (int)(s->p1 - s->p0); //----------------------отладочная------
  758.     e2_DA = s->sizefile;
  759.  
  760.     if(k<0) return(-1);
  761.     return(0);
  762. }
  763.  
  764. //---------------- fjp_fun -----------------
  765.  
  766. int fjp_fun(struct s_fjp *s)
  767. {
  768.     int dl, mark;
  769.  
  770. START:
  771.  
  772.     mark=fjp_get_marker(s); // взять маркер
  773.  
  774. #if FJP_FL_TEST > 0
  775.     if(mark<0) printf("mark=%d\n", mark);
  776.     else printf("mark=0x%02X\n", mark);
  777. #endif
  778.  
  779.     if(mark<0) goto ERR;
  780.     if(s->fl > 0){
  781.         if(fjp_putc_fp(0xFF, s) < 0) goto ERR;
  782.         if(fjp_putc_fp(mark, s) < 0) goto ERR;
  783.     }
  784.     //маркеры, не имеющие длины
  785.     if(mark==0xD9) goto RET; // конец файла
  786.     if((mark & 0xF7)==0xD0) goto START;
  787.  
  788.     //эти сегменты копировать без обработки
  789.     if(mark==0xFE || (mark & 0xF0)==0xE0 || mark==0xDB){
  790.         if(fjp_rol_segment(s->buf, sizeof(s->buf), s) < 0) goto ERR;
  791.         goto START;
  792.     }
  793.  
  794.     //другие сегменты обрабатывать
  795.     dl=fjp_get_segment(s->buf, sizeof(s->buf), s);
  796.     if(dl<0) goto ERR;
  797.     //0xC4, таблицы Хаффмана, обрабатывается особым образом, не копировать
  798.     if(mark==0xC4){
  799.         if(fjp_decode_C4(s, s->buf, dl) < 0) goto ERR;
  800.         goto START;
  801.     }
  802.  
  803.     if(s->fl > 0){ //копирование. Для 0xDA копирует заголовк
  804.         if(fjp_putc_fp((dl+2) >> 8, s) < 0) goto ERR;
  805.         if(fjp_putc_fp((dl+2), s) < 0) goto ERR;
  806.         if(fjp_fwrite_fp(s->buf, dl, 1, s) < 0) goto ERR;
  807.     }
  808.     //обработка
  809.     if(mark==0xC0){ // ширина, высота, прореживание, id таблиц квантования
  810.         if(fjp_decode_C0(s, s->buf, dl) < 0) goto ERR;
  811.     }
  812.     else if(mark==0xDD){ // рестарт
  813.         if(fjp_decode_DD(s, s->buf, dl) < 0) goto ERR;
  814.     }
  815.     else if(mark==0xDA){ // графика
  816.         if(s->fl_start > 0){ s->err = FJP_ERR_SYNTAX; goto ERR;}
  817.         s->fl_start++;
  818.         if(fjp_decode_DA(s, s->buf, dl) < 0) goto ERR;
  819.     }
  820.     else { s->err = FJP_ERR_NOT_SUPPORT; goto ERR;}
  821.     goto START;
  822.  
  823. RET:
  824.     if(s->fl_start == 0){ s->err = FJP_ERR_SYNTAX; goto ERR;}
  825.     return(0);
  826.  
  827. ERR:
  828.     return(-1);
  829. }
  830.  
  831. //------------ fjp_fun_1 ---------------
  832.  
  833. int fjp_fun_1(struct s_fjp *s)
  834. {
  835.     int i, k;
  836.     struct s_fjp1 *s1;
  837.  
  838.     if(fjp_fun(s) < 0) return(-1); //первый проход
  839.  
  840.     fjp_init_struct(s, s->p0, s->p2 - s->p0, s->s1, s->fp);
  841.     s->fl = 1;
  842.     s1 = s->s1;
  843.     for(i=0; i<8; i++){
  844.         k = fjp_hfm_code(s1->tree, s1->fsym[i].sym, s1->fsym[i].buf);
  845.         s1->fsym[i].n = k;
  846.  
  847. #if FJP_FL_TEST > 0
  848.         if(fl>0){ //--------------------------------------отладочная------
  849.             printf("-----maxlen=%d; ", maxlen);
  850.             if(i<4) printf("DC[%d]\n", i);
  851.             else printf("AC[%d]\n", i-4);
  852.             fl=0;
  853.         }
  854. #endif
  855.  
  856.     }
  857.  
  858.     n1_FF = n2_FF = d1_C4 = d2_C4 = 0; //------------------отладочная------
  859.  
  860. #if FJP_FL_TEST > 0
  861.     printf("----------\n");
  862. #endif
  863.  
  864.     k = fjp_fun(s); //второй проход
  865.     return(k);
  866. }
  867.  
  868. //---------------- fjp_opt_hfm ------------------
  869.  
  870. int fjp_opt_hfm(const char *in_buf, int len_in_buf, FILE *fp,
  871.                 int *w, int *h, int *err)
  872. {
  873.     struct s_fjp   *s = NULL;
  874.     struct s_fjp1  *s1=NULL;
  875.     int k, err0;
  876.  
  877.     if(in_buf==NULL || len_in_buf <= 0 || fp==NULL || w==NULL || h==NULL){
  878.         err0 = FJP_ERR_INVAL; goto ERR;
  879.     }
  880.     *w = *h =0;
  881.     s = (struct s_fjp*)malloc(sizeof(struct s_fjp));
  882.     if(s==NULL){ err0 = FJP_ERR_MEMORY; goto ERR;}
  883.     s1 = (struct s_fjp1*)malloc(sizeof(struct s_fjp1));
  884.     if(s1==NULL){ err0 = FJP_ERR_MEMORY; goto ERR;}
  885.     fjp_init_struct(s, in_buf, len_in_buf, s1, fp);
  886.     memset(s1, 0, sizeof(struct s_fjp1));
  887.     k=fjp_fun_1(s);
  888.     if(k<0){ err0 = s->err; goto ERR;}
  889.     k = s->sizefile;
  890.     *w = s->w;
  891.     *h = s->h;
  892.     free(s);
  893.     free(s1);
  894.     if(err != NULL) *err=0;
  895.     return(k);
  896.  
  897. ERR:
  898.     if(s != NULL) free(s);
  899.     if(s1 != NULL) free(s1);
  900.     if(err != NULL) *err = err0;
  901.     return(-1);
  902. }
  903.  
  904. //---------- fjp_strerror -----------
  905.  
  906. const char *fjp_strerror(int err)
  907. {
  908.     switch(err){
  909.         case FJP_ERR_RD_FILE     : return("FJP_ERR_RD_FILE");
  910.         case FJP_ERR_SYNTAX      : return("FJP_ERR_SYNTAX");
  911.         case FJP_ERR_NOT_SUPPORT : return("FJP_ERR_NOT_SUPPORT");
  912.         case FJP_ERR_MEMORY      : return("FJP_ERR_MEMORY");
  913.         case FJP_ERR_DECODE      : return("FJP_ERR_DECODE");
  914.         case FJP_ERR_INVAL       : return("FJP_ERR_INVAL");
  915.         case FJP_ERR_WR_FILE     : return("FJP_ERR_WR_FILE");
  916.     }
  917.     return("FJP: Unknow error");
  918. }
  919.  
  920. #if 1
  921. //============= Тестовая обертка ====================
  922.  
  923.  
  924. // Аргументом указать имя входного JPEG-файла. После работы программы
  925. // должен получиться оптимизированный файл "test.jpg".
  926.  
  927. #include <sys/time.h>
  928.  
  929. //------------- gettime_dt_mks ---------------
  930. // разность двух временных меток в миллисекундах
  931. int gettime_dt_msek(struct timeval *tv1, struct timeval *tv2)
  932. {
  933.     return((tv2->tv_sec - tv1->tv_sec)*1000 +
  934.            (tv2->tv_usec - tv1->tv_usec + 500)/1000);
  935. }
  936.  
  937. //---------------- fjp_opt_hfm_1 ------------------
  938. // обертка для fjp_opt_hfm()
  939. int fjp_opt_hfm_1(const char *f1, const char *f2)
  940. {
  941.     FILE *fp1=NULL, *fp2=NULL;
  942.     int k, dl1, dl2, w, h, err, t;
  943.     char *buf=NULL;
  944.     struct timeval tv1, tv2;
  945.  
  946.     fp1=fopen(f1, "r");
  947.     if(fp1==NULL){ printf("fp1=fopen(%s)=NULL\n", f1); goto ERR;}
  948.  
  949.     // измерение длины JPEG-файла
  950.     fseek(fp1, 0, SEEK_END);
  951.     dl1 = ftell(fp1);
  952.     rewind(fp1);
  953.  
  954.     fp2=fopen(f2, "w");
  955.     if(fp2==NULL){ printf("fp2=fopen(%s)=NULL\n", f2); goto ERR;}
  956.  
  957.     buf = (char*)malloc(dl1);
  958.     if(buf==NULL){ printf("buf = (char*)malloc(dl1)=NULL\n"); goto ERR;}
  959.     k = fread(buf, dl1, 1, fp1);
  960.     if(k != 1){ printf("k = fread(fp1)=%d\n", k); goto ERR;}
  961.     fclose(fp1); fp1=NULL;
  962.     printf("-------------\n");
  963.  
  964.     gettimeofday(&tv1, NULL);
  965.     dl2 = fjp_opt_hfm(buf, dl1, fp2, &w, &h, &err); // оптимизация
  966.     gettimeofday(&tv2, NULL);
  967.     t = gettime_dt_msek(&tv1, &tv2);
  968.  
  969.     printf("-------------\n");
  970.     printf("dl2 = fjp_opt_hfm()=%d; err=%d; ", dl2, err);
  971.     printf("%s\n", err==0 ? "" : fjp_strerror(err));
  972.     printf("w=%d; h=%d\n", w, h);
  973.     printf("t=%d.%03d sec\n", t/1000, t%1000);
  974.     printf("dl1=%d\n", dl1);
  975.     printf("dl2=%d\n", dl2);
  976.     printf("n1_FF=%d\n", n1_FF);
  977.     printf("n2_FF=%d\n", n2_FF);
  978.     printf("delta_FF=%d\n", n1_FF - n2_FF);
  979.     printf("d1_DA=%d\n", e1_DA - b1_DA);
  980.     printf("d2_DA=%d\n", e2_DA - b2_DA);
  981.     printf("delta_DA=%d\n", (e1_DA - b1_DA) - (e2_DA - b2_DA));
  982.     printf("delta_C4=%d\n", d1_C4 - d2_C4);
  983.     printf("delta_dl=%d\n", dl1 - dl2);
  984.     if(dl1>0 && dl2>0){
  985.         printf("Compress=%0.2f %%\n", 100.0 * dl2 / dl1);
  986.     }
  987.     free(buf);
  988.     fclose(fp2);
  989.     printf("-------------\n");
  990.     return(0);
  991.  
  992. ERR:
  993.     if(buf != NULL) free(buf);
  994.     if(fp1 != NULL) fclose(fp1);
  995.     if(fp2 != NULL) fclose(fp2);
  996.     printf("-------------\n");
  997.     return(-1);
  998. }
  999.  
  1000. //-------- main --------------------
  1001. // printf("\n");
  1002. int main(int argc, char **argv)
  1003. {
  1004.     const char *f2="test.jpg";
  1005.  
  1006.     if(argc < 2){ printf("Err-arg\n"); exit(0);}
  1007.  
  1008.     fjp_opt_hfm_1(argv[1], f2);
  1009.  
  1010.     exit(0);
  1011. }
  1012. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement