/libavcodec/mqcenc.c

http://github.com/FFmpeg/FFmpeg · C · 139 lines · 103 code · 11 blank · 25 comment · 20 complexity · 82807a14b650b55de776cce46bbab6d6 MD5 · raw file

  1. /*
  2. * MQ-coder encoder
  3. * Copyright (c) 2007 Kamil Nowosad
  4. *
  5. * This file is part of FFmpeg.
  6. *
  7. * FFmpeg is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * FFmpeg is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with FFmpeg; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. /**
  22. * MQ-coder encoder
  23. * @file
  24. * @author Kamil Nowosad
  25. */
  26. #include "libavutil/avassert.h"
  27. #include "mqc.h"
  28. static void byteout(MqcState *mqc)
  29. {
  30. retry:
  31. if (*mqc->bp == 0xff){
  32. mqc->bp++;
  33. *mqc->bp = mqc->c >> 20;
  34. mqc->c &= 0xfffff;
  35. mqc->ct = 7;
  36. } else if ((mqc->c & 0x8000000)){
  37. (*mqc->bp)++;
  38. mqc->c &= 0x7ffffff;
  39. goto retry;
  40. } else{
  41. mqc->bp++;
  42. *mqc->bp = mqc->c >> 19;
  43. mqc->c &= 0x7ffff;
  44. mqc->ct = 8;
  45. }
  46. }
  47. static void renorme(MqcState *mqc)
  48. {
  49. do{
  50. mqc->a += mqc->a;
  51. mqc->c += mqc->c;
  52. if (!--mqc->ct)
  53. byteout(mqc);
  54. } while (!(mqc->a & 0x8000));
  55. }
  56. static void setbits(MqcState *mqc)
  57. {
  58. int tmp = mqc->c + mqc->a;
  59. mqc->c |= 0xffff;
  60. if (mqc->c >= tmp)
  61. mqc->c -= 0x8000;
  62. }
  63. void ff_mqc_initenc(MqcState *mqc, uint8_t *bp)
  64. {
  65. ff_mqc_init_contexts(mqc);
  66. mqc->a = 0x8000;
  67. mqc->c = 0;
  68. mqc->bp = bp-1;
  69. mqc->bpstart = bp;
  70. mqc->ct = 12 + (*mqc->bp == 0xff);
  71. }
  72. void ff_mqc_encode(MqcState *mqc, uint8_t *cxstate, int d)
  73. {
  74. int qe;
  75. qe = ff_mqc_qe[*cxstate];
  76. mqc->a -= qe;
  77. if ((*cxstate & 1) == d){
  78. if (!(mqc->a & 0x8000)){
  79. if (mqc->a < qe)
  80. mqc->a = qe;
  81. else
  82. mqc->c += qe;
  83. *cxstate = ff_mqc_nmps[*cxstate];
  84. renorme(mqc);
  85. } else
  86. mqc->c += qe;
  87. } else{
  88. if (mqc->a < qe)
  89. mqc->c += qe;
  90. else
  91. mqc->a = qe;
  92. *cxstate = ff_mqc_nlps[*cxstate];
  93. renorme(mqc);
  94. }
  95. }
  96. int ff_mqc_length(MqcState *mqc)
  97. {
  98. return mqc->bp - mqc->bpstart;
  99. }
  100. int ff_mqc_flush(MqcState *mqc)
  101. {
  102. setbits(mqc);
  103. mqc->c = mqc->c << mqc->ct;
  104. byteout(mqc);
  105. mqc->c = mqc->c << mqc->ct;
  106. byteout(mqc);
  107. if (*mqc->bp != 0xff)
  108. mqc->bp++;
  109. return mqc->bp - mqc->bpstart;
  110. }
  111. int ff_mqc_flush_to(MqcState *mqc, uint8_t *dst, int *dst_len)
  112. {
  113. MqcState mqc2 = *mqc;
  114. mqc2.bpstart=
  115. mqc2.bp = dst;
  116. *mqc2.bp = *mqc->bp;
  117. ff_mqc_flush(&mqc2);
  118. *dst_len = mqc2.bp - dst;
  119. if (mqc->bp < mqc->bpstart) {
  120. av_assert1(mqc->bpstart - mqc->bp == 1);
  121. av_assert1(*dst_len > 0);
  122. av_assert1(mqc->bp[0] == 0 && dst[0] == 0);
  123. (*dst_len) --;
  124. memmove(dst, dst+1, *dst_len);
  125. return mqc->bp - mqc->bpstart + 1 + *dst_len;
  126. }
  127. return mqc->bp - mqc->bpstart + *dst_len;
  128. }