• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavcodec/lcldec.c

Go to the documentation of this file.
00001 /*
00002  * LCL (LossLess Codec Library) Codec
00003  * Copyright (c) 2002-2004 Roberto Togni
00004  *
00005  * This file is part of FFmpeg.
00006  *
00007  * FFmpeg is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * FFmpeg is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with FFmpeg; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00041 #include <stdio.h>
00042 #include <stdlib.h>
00043 
00044 #include "avcodec.h"
00045 #include "bitstream.h"
00046 #include "lcl.h"
00047 
00048 #if CONFIG_ZLIB
00049 #include <zlib.h>
00050 #endif
00051 
00052 /*
00053  * Decoder context
00054  */
00055 typedef struct LclDecContext {
00056     AVFrame pic;
00057 
00058     // Image type
00059     int imgtype;
00060     // Compression type
00061     int compression;
00062     // Flags
00063     int flags;
00064     // Decompressed data size
00065     unsigned int decomp_size;
00066     // Decompression buffer
00067     unsigned char* decomp_buf;
00068 #if CONFIG_ZLIB
00069     z_stream zstream;
00070 #endif
00071 } LclDecContext;
00072 
00073 
00074 /*
00075  *
00076  * Helper functions
00077  *
00078  */
00079 static inline unsigned char fix (int pix14)
00080 {
00081     int tmp;
00082 
00083     tmp = (pix14 + 0x80000) >> 20;
00084     if (tmp < 0)
00085         return 0;
00086     if (tmp > 255)
00087         return 255;
00088     return tmp;
00089 }
00090 
00091 
00092 
00093 static inline unsigned char get_b (unsigned char yq, signed char bq)
00094 {
00095     return fix((yq << 20) + bq * 1858076);
00096 }
00097 
00098 
00099 
00100 static inline unsigned char get_g (unsigned char yq, signed char bq, signed char rq)
00101 {
00102     return fix((yq << 20) - bq * 360857 - rq * 748830);
00103 }
00104 
00105 
00106 
00107 static inline unsigned char get_r (unsigned char yq, signed char rq)
00108 {
00109     return fix((yq << 20) + rq * 1470103);
00110 }
00111 
00112 
00113 
00114 static unsigned int mszh_decomp(unsigned char * srcptr, int srclen, unsigned char * destptr, unsigned int destsize)
00115 {
00116     unsigned char *destptr_bak = destptr;
00117     unsigned char *destptr_end = destptr + destsize;
00118     unsigned char mask = 0;
00119     unsigned char maskbit = 0;
00120     unsigned int ofs, cnt;
00121 
00122     while ((srclen > 0) && (destptr < destptr_end)) {
00123         if (maskbit == 0) {
00124             mask = *(srcptr++);
00125             maskbit = 8;
00126             srclen--;
00127             continue;
00128         }
00129         if ((mask & (1 << (--maskbit))) == 0) {
00130             if (destptr + 4 > destptr_end)
00131                 break;
00132             *(int*)destptr = *(int*)srcptr;
00133             srclen -= 4;
00134             destptr += 4;
00135             srcptr += 4;
00136         } else {
00137             ofs = *(srcptr++);
00138             cnt = *(srcptr++);
00139             ofs += cnt * 256;
00140             cnt = ((cnt >> 3) & 0x1f) + 1;
00141             ofs &= 0x7ff;
00142             srclen -= 2;
00143             cnt *= 4;
00144             if (destptr + cnt > destptr_end) {
00145                 cnt =  destptr_end - destptr;
00146             }
00147             for (; cnt > 0; cnt--) {
00148                 *(destptr) = *(destptr - ofs);
00149                 destptr++;
00150             }
00151         }
00152     }
00153 
00154     return (destptr - destptr_bak);
00155 }
00156 
00157 
00158 
00159 /*
00160  *
00161  * Decode a frame
00162  *
00163  */
00164 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size)
00165 {
00166     LclDecContext * const c = avctx->priv_data;
00167     unsigned char *encoded = (unsigned char *)buf;
00168     unsigned int pixel_ptr;
00169     int row, col;
00170     unsigned char *outptr;
00171     unsigned int width = avctx->width; // Real image width
00172     unsigned int height = avctx->height; // Real image height
00173     unsigned int mszh_dlen;
00174     unsigned char yq, y1q, uq, vq;
00175     int uqvq;
00176     unsigned int mthread_inlen, mthread_outlen;
00177 #if CONFIG_ZLIB
00178     int zret; // Zlib return code
00179 #endif
00180     unsigned int len = buf_size;
00181 
00182     if(c->pic.data[0])
00183         avctx->release_buffer(avctx, &c->pic);
00184 
00185     c->pic.reference = 0;
00186     c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
00187     if(avctx->get_buffer(avctx, &c->pic) < 0){
00188         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00189         return -1;
00190     }
00191 
00192     outptr = c->pic.data[0]; // Output image pointer
00193 
00194     /* Decompress frame */
00195     switch (avctx->codec_id) {
00196     case CODEC_ID_MSZH:
00197         switch (c->compression) {
00198         case COMP_MSZH:
00199             if (c->flags & FLAG_MULTITHREAD) {
00200                 mthread_inlen = *((unsigned int*)encoded);
00201                 mthread_outlen = *((unsigned int*)(encoded+4));
00202                 if (mthread_outlen > c->decomp_size) // this should not happen
00203                     mthread_outlen = c->decomp_size;
00204                 mszh_dlen = mszh_decomp(encoded + 8, mthread_inlen, c->decomp_buf, c->decomp_size);
00205                 if (mthread_outlen != mszh_dlen) {
00206                     av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%d != %d)\n",
00207                            mthread_outlen, mszh_dlen);
00208                     return -1;
00209                 }
00210                 mszh_dlen = mszh_decomp(encoded + 8 + mthread_inlen, len - mthread_inlen,
00211                                         c->decomp_buf + mthread_outlen, c->decomp_size - mthread_outlen);
00212                 if (mthread_outlen != mszh_dlen) {
00213                     av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %d)\n",
00214                            mthread_outlen, mszh_dlen);
00215                     return -1;
00216                 }
00217                 encoded = c->decomp_buf;
00218                 len = c->decomp_size;
00219             } else {
00220                 mszh_dlen = mszh_decomp(encoded, len, c->decomp_buf, c->decomp_size);
00221                 if (c->decomp_size != mszh_dlen) {
00222                     av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %d)\n",
00223                            c->decomp_size, mszh_dlen);
00224                     return -1;
00225                 }
00226                 encoded = c->decomp_buf;
00227                 len = mszh_dlen;
00228             }
00229             break;
00230         case COMP_MSZH_NOCOMP:
00231             break;
00232         default:
00233             av_log(avctx, AV_LOG_ERROR, "BUG! Unknown MSZH compression in frame decoder.\n");
00234             return -1;
00235         }
00236         break;
00237     case CODEC_ID_ZLIB:
00238 #if CONFIG_ZLIB
00239         /* Using the original dll with normal compression (-1) and RGB format
00240          * gives a file with ZLIB fourcc, but frame is really uncompressed.
00241          * To be sure that's true check also frame size */
00242         if ((c->compression == COMP_ZLIB_NORMAL) && (c->imgtype == IMGTYPE_RGB24) &&
00243             (len == width * height * 3))
00244             break;
00245         zret = inflateReset(&(c->zstream));
00246         if (zret != Z_OK) {
00247             av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
00248             return -1;
00249         }
00250         if (c->flags & FLAG_MULTITHREAD) {
00251             mthread_inlen = *((unsigned int*)encoded);
00252             mthread_outlen = *((unsigned int*)(encoded+4));
00253             if (mthread_outlen > c->decomp_size)
00254                 mthread_outlen = c->decomp_size;
00255             c->zstream.next_in = encoded + 8;
00256             c->zstream.avail_in = mthread_inlen;
00257             c->zstream.next_out = c->decomp_buf;
00258             c->zstream.avail_out = c->decomp_size;
00259             zret = inflate(&(c->zstream), Z_FINISH);
00260             if ((zret != Z_OK) && (zret != Z_STREAM_END)) {
00261                 av_log(avctx, AV_LOG_ERROR, "Mthread1 inflate error: %d\n", zret);
00262                 return -1;
00263             }
00264             if (mthread_outlen != (unsigned int)(c->zstream.total_out)) {
00265                 av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%u != %lu)\n",
00266                        mthread_outlen, c->zstream.total_out);
00267                 return -1;
00268             }
00269             zret = inflateReset(&(c->zstream));
00270             if (zret != Z_OK) {
00271                 av_log(avctx, AV_LOG_ERROR, "Mthread2 inflate reset error: %d\n", zret);
00272                 return -1;
00273             }
00274             c->zstream.next_in = encoded + 8 + mthread_inlen;
00275             c->zstream.avail_in = len - mthread_inlen;
00276             c->zstream.next_out = c->decomp_buf + mthread_outlen;
00277             c->zstream.avail_out = c->decomp_size - mthread_outlen;
00278             zret = inflate(&(c->zstream), Z_FINISH);
00279             if ((zret != Z_OK) && (zret != Z_STREAM_END)) {
00280                 av_log(avctx, AV_LOG_ERROR, "Mthread2 inflate error: %d\n", zret);
00281                 return -1;
00282             }
00283             if (mthread_outlen != (unsigned int)(c->zstream.total_out)) {
00284                 av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %lu)\n",
00285                        mthread_outlen, c->zstream.total_out);
00286                 return -1;
00287             }
00288         } else {
00289             c->zstream.next_in = encoded;
00290             c->zstream.avail_in = len;
00291             c->zstream.next_out = c->decomp_buf;
00292             c->zstream.avail_out = c->decomp_size;
00293             zret = inflate(&(c->zstream), Z_FINISH);
00294             if ((zret != Z_OK) && (zret != Z_STREAM_END)) {
00295                 av_log(avctx, AV_LOG_ERROR, "Inflate error: %d\n", zret);
00296                 return -1;
00297             }
00298             if (c->decomp_size != (unsigned int)(c->zstream.total_out)) {
00299                 av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %lu)\n",
00300                        c->decomp_size, c->zstream.total_out);
00301                 return -1;
00302             }
00303         }
00304         encoded = c->decomp_buf;
00305         len = c->decomp_size;
00306 #else
00307         av_log(avctx, AV_LOG_ERROR, "BUG! Zlib support not compiled in frame decoder.\n");
00308         return -1;
00309 #endif
00310         break;
00311     default:
00312         av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in frame decoder compression switch.\n");
00313         return -1;
00314     }
00315 
00316 
00317     /* Apply PNG filter */
00318     if ((avctx->codec_id == CODEC_ID_ZLIB) && (c->flags & FLAG_PNGFILTER)) {
00319         switch (c->imgtype) {
00320         case IMGTYPE_YUV111:
00321         case IMGTYPE_RGB24:
00322             for (row = 0; row < height; row++) {
00323                 pixel_ptr = row * width * 3;
00324                 yq = encoded[pixel_ptr++];
00325                 uqvq = AV_RL16(encoded+pixel_ptr);
00326                 pixel_ptr += 2;
00327                 for (col = 1; col < width; col++) {
00328                     encoded[pixel_ptr] = yq -= encoded[pixel_ptr];
00329                     uqvq -= AV_RL16(encoded+pixel_ptr+1);
00330                     AV_WL16(encoded+pixel_ptr+1, uqvq);
00331                     pixel_ptr += 3;
00332                 }
00333             }
00334             break;
00335         case IMGTYPE_YUV422:
00336             for (row = 0; row < height; row++) {
00337                 pixel_ptr = row * width * 2;
00338                 yq = uq = vq =0;
00339                 for (col = 0; col < width/4; col++) {
00340                     encoded[pixel_ptr] = yq -= encoded[pixel_ptr];
00341                     encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1];
00342                     encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2];
00343                     encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3];
00344                     encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4];
00345                     encoded[pixel_ptr+5] = uq -= encoded[pixel_ptr+5];
00346                     encoded[pixel_ptr+6] = vq -= encoded[pixel_ptr+6];
00347                     encoded[pixel_ptr+7] = vq -= encoded[pixel_ptr+7];
00348                     pixel_ptr += 8;
00349                 }
00350             }
00351             break;
00352         case IMGTYPE_YUV411:
00353             for (row = 0; row < height; row++) {
00354                 pixel_ptr = row * width / 2 * 3;
00355                 yq = uq = vq =0;
00356                 for (col = 0; col < width/4; col++) {
00357                     encoded[pixel_ptr] = yq -= encoded[pixel_ptr];
00358                     encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1];
00359                     encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2];
00360                     encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3];
00361                     encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4];
00362                     encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5];
00363                     pixel_ptr += 6;
00364                 }
00365             }
00366             break;
00367         case IMGTYPE_YUV211:
00368             for (row = 0; row < height; row++) {
00369                 pixel_ptr = row * width * 2;
00370                 yq = uq = vq =0;
00371                 for (col = 0; col < width/2; col++) {
00372                     encoded[pixel_ptr] = yq -= encoded[pixel_ptr];
00373                     encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1];
00374                     encoded[pixel_ptr+2] = uq -= encoded[pixel_ptr+2];
00375                     encoded[pixel_ptr+3] = vq -= encoded[pixel_ptr+3];
00376                     pixel_ptr += 4;
00377                 }
00378             }
00379             break;
00380         case IMGTYPE_YUV420:
00381             for (row = 0; row < height/2; row++) {
00382                 pixel_ptr = row * width * 3;
00383                 yq = y1q = uq = vq =0;
00384                 for (col = 0; col < width/2; col++) {
00385                     encoded[pixel_ptr] = yq -= encoded[pixel_ptr];
00386                     encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1];
00387                     encoded[pixel_ptr+2] = y1q -= encoded[pixel_ptr+2];
00388                     encoded[pixel_ptr+3] = y1q -= encoded[pixel_ptr+3];
00389                     encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4];
00390                     encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5];
00391                     pixel_ptr += 6;
00392                 }
00393             }
00394             break;
00395         default:
00396             av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in pngfilter switch.\n");
00397             return -1;
00398         }
00399     }
00400 
00401     /* Convert colorspace */
00402     switch (c->imgtype) {
00403     case IMGTYPE_YUV111:
00404         for (row = height - 1; row >= 0; row--) {
00405             pixel_ptr = row * c->pic.linesize[0];
00406             for (col = 0; col < width; col++) {
00407                 outptr[pixel_ptr++] = get_b(encoded[0], encoded[1]);
00408                 outptr[pixel_ptr++] = get_g(encoded[0], encoded[1], encoded[2]);
00409                 outptr[pixel_ptr++] = get_r(encoded[0], encoded[2]);
00410                 encoded += 3;
00411             }
00412         }
00413         break;
00414     case IMGTYPE_YUV422:
00415         for (row = height - 1; row >= 0; row--) {
00416             pixel_ptr = row * c->pic.linesize[0];
00417             for (col = 0; col < width/4; col++) {
00418                 outptr[pixel_ptr++] = get_b(encoded[0], encoded[4]);
00419                 outptr[pixel_ptr++] = get_g(encoded[0], encoded[4], encoded[6]);
00420                 outptr[pixel_ptr++] = get_r(encoded[0], encoded[6]);
00421                 outptr[pixel_ptr++] = get_b(encoded[1], encoded[4]);
00422                 outptr[pixel_ptr++] = get_g(encoded[1], encoded[4], encoded[6]);
00423                 outptr[pixel_ptr++] = get_r(encoded[1], encoded[6]);
00424                 outptr[pixel_ptr++] = get_b(encoded[2], encoded[5]);
00425                 outptr[pixel_ptr++] = get_g(encoded[2], encoded[5], encoded[7]);
00426                 outptr[pixel_ptr++] = get_r(encoded[2], encoded[7]);
00427                 outptr[pixel_ptr++] = get_b(encoded[3], encoded[5]);
00428                 outptr[pixel_ptr++] = get_g(encoded[3], encoded[5], encoded[7]);
00429                 outptr[pixel_ptr++] = get_r(encoded[3], encoded[7]);
00430                 encoded += 8;
00431             }
00432         }
00433         break;
00434     case IMGTYPE_RGB24:
00435         for (row = height - 1; row >= 0; row--) {
00436             pixel_ptr = row * c->pic.linesize[0];
00437             for (col = 0; col < width; col++) {
00438                 outptr[pixel_ptr++] = encoded[0];
00439                 outptr[pixel_ptr++] = encoded[1];
00440                 outptr[pixel_ptr++] = encoded[2];
00441                 encoded += 3;
00442             }
00443         }
00444         break;
00445     case IMGTYPE_YUV411:
00446         for (row = height - 1; row >= 0; row--) {
00447             pixel_ptr = row * c->pic.linesize[0];
00448             for (col = 0; col < width/4; col++) {
00449                 outptr[pixel_ptr++] = get_b(encoded[0], encoded[4]);
00450                 outptr[pixel_ptr++] = get_g(encoded[0], encoded[4], encoded[5]);
00451                 outptr[pixel_ptr++] = get_r(encoded[0], encoded[5]);
00452                 outptr[pixel_ptr++] = get_b(encoded[1], encoded[4]);
00453                 outptr[pixel_ptr++] = get_g(encoded[1], encoded[4], encoded[5]);
00454                 outptr[pixel_ptr++] = get_r(encoded[1], encoded[5]);
00455                 outptr[pixel_ptr++] = get_b(encoded[2], encoded[4]);
00456                 outptr[pixel_ptr++] = get_g(encoded[2], encoded[4], encoded[5]);
00457                 outptr[pixel_ptr++] = get_r(encoded[2], encoded[5]);
00458                 outptr[pixel_ptr++] = get_b(encoded[3], encoded[4]);
00459                 outptr[pixel_ptr++] = get_g(encoded[3], encoded[4], encoded[5]);
00460                 outptr[pixel_ptr++] = get_r(encoded[3], encoded[5]);
00461                 encoded += 6;
00462             }
00463         }
00464         break;
00465     case IMGTYPE_YUV211:
00466         for (row = height - 1; row >= 0; row--) {
00467             pixel_ptr = row * c->pic.linesize[0];
00468             for (col = 0; col < width/2; col++) {
00469                 outptr[pixel_ptr++] = get_b(encoded[0], encoded[2]);
00470                 outptr[pixel_ptr++] = get_g(encoded[0], encoded[2], encoded[3]);
00471                 outptr[pixel_ptr++] = get_r(encoded[0], encoded[3]);
00472                 outptr[pixel_ptr++] = get_b(encoded[1], encoded[2]);
00473                 outptr[pixel_ptr++] = get_g(encoded[1], encoded[2], encoded[3]);
00474                 outptr[pixel_ptr++] = get_r(encoded[1], encoded[3]);
00475                 encoded += 4;
00476             }
00477         }
00478         break;
00479     case IMGTYPE_YUV420:
00480         for (row = height / 2 - 1; row >= 0; row--) {
00481             pixel_ptr = 2 * row * c->pic.linesize[0];
00482             for (col = 0; col < width/2; col++) {
00483                 outptr[pixel_ptr] = get_b(encoded[0], encoded[4]);
00484                 outptr[pixel_ptr+1] = get_g(encoded[0], encoded[4], encoded[5]);
00485                 outptr[pixel_ptr+2] = get_r(encoded[0], encoded[5]);
00486                 outptr[pixel_ptr+3] = get_b(encoded[1], encoded[4]);
00487                 outptr[pixel_ptr+4] = get_g(encoded[1], encoded[4], encoded[5]);
00488                 outptr[pixel_ptr+5] = get_r(encoded[1], encoded[5]);
00489                 outptr[pixel_ptr-c->pic.linesize[0]] = get_b(encoded[2], encoded[4]);
00490                 outptr[pixel_ptr-c->pic.linesize[0]+1] = get_g(encoded[2], encoded[4], encoded[5]);
00491                 outptr[pixel_ptr-c->pic.linesize[0]+2] = get_r(encoded[2], encoded[5]);
00492                 outptr[pixel_ptr-c->pic.linesize[0]+3] = get_b(encoded[3], encoded[4]);
00493                 outptr[pixel_ptr-c->pic.linesize[0]+4] = get_g(encoded[3], encoded[4], encoded[5]);
00494                 outptr[pixel_ptr-c->pic.linesize[0]+5] = get_r(encoded[3], encoded[5]);
00495                 pixel_ptr += 6;
00496                 encoded += 6;
00497             }
00498         }
00499         break;
00500     default:
00501         av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in image decoder.\n");
00502         return -1;
00503     }
00504 
00505     *data_size = sizeof(AVFrame);
00506     *(AVFrame*)data = c->pic;
00507 
00508     /* always report that the buffer was completely consumed */
00509     return buf_size;
00510 }
00511 
00512 /*
00513  *
00514  * Init lcl decoder
00515  *
00516  */
00517 static av_cold int decode_init(AVCodecContext *avctx)
00518 {
00519     LclDecContext * const c = avctx->priv_data;
00520     unsigned int basesize = avctx->width * avctx->height;
00521     unsigned int max_basesize = ((avctx->width + 3) & ~3) * ((avctx->height + 3) & ~3);
00522     unsigned int max_decomp_size;
00523     int zret; // Zlib return code
00524 
00525     c->pic.data[0] = NULL;
00526 
00527 #if CONFIG_ZLIB
00528     // Needed if zlib unused or init aborted before inflateInit
00529     memset(&(c->zstream), 0, sizeof(z_stream));
00530 #endif
00531 
00532     if (avctx->extradata_size < 8) {
00533         av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n");
00534         return 1;
00535     }
00536 
00537     if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) {
00538         return 1;
00539     }
00540 
00541     /* Check codec type */
00542     if (((avctx->codec_id == CODEC_ID_MSZH)  && (*((char *)avctx->extradata + 7) != CODEC_MSZH)) ||
00543         ((avctx->codec_id == CODEC_ID_ZLIB)  && (*((char *)avctx->extradata + 7) != CODEC_ZLIB))) {
00544         av_log(avctx, AV_LOG_ERROR, "Codec id and codec type mismatch. This should not happen.\n");
00545     }
00546 
00547     /* Detect image type */
00548     switch (c->imgtype = *((char *)avctx->extradata + 4)) {
00549     case IMGTYPE_YUV111:
00550         c->decomp_size = basesize * 3;
00551         max_decomp_size = max_basesize * 3;
00552         av_log(avctx, AV_LOG_INFO, "Image type is YUV 1:1:1.\n");
00553         break;
00554     case IMGTYPE_YUV422:
00555         c->decomp_size = basesize * 2;
00556         max_decomp_size = max_basesize * 2;
00557         av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:2:2.\n");
00558         break;
00559     case IMGTYPE_RGB24:
00560         c->decomp_size = basesize * 3;
00561         max_decomp_size = max_basesize * 3;
00562         av_log(avctx, AV_LOG_INFO, "Image type is RGB 24.\n");
00563         break;
00564     case IMGTYPE_YUV411:
00565         c->decomp_size = basesize / 2 * 3;
00566         max_decomp_size = max_basesize / 2 * 3;
00567         av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:1:1.\n");
00568         break;
00569     case IMGTYPE_YUV211:
00570         c->decomp_size = basesize * 2;
00571         max_decomp_size = max_basesize * 2;
00572         av_log(avctx, AV_LOG_INFO, "Image type is YUV 2:1:1.\n");
00573         break;
00574     case IMGTYPE_YUV420:
00575         c->decomp_size = basesize / 2 * 3;
00576         max_decomp_size = max_basesize / 2 * 3;
00577         av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:2:0.\n");
00578         break;
00579     default:
00580         av_log(avctx, AV_LOG_ERROR, "Unsupported image format %d.\n", c->imgtype);
00581         return 1;
00582     }
00583 
00584     /* Detect compression method */
00585     c->compression = *((char *)avctx->extradata + 5);
00586     switch (avctx->codec_id) {
00587     case CODEC_ID_MSZH:
00588         switch (c->compression) {
00589         case COMP_MSZH:
00590             av_log(avctx, AV_LOG_INFO, "Compression enabled.\n");
00591             break;
00592         case COMP_MSZH_NOCOMP:
00593             c->decomp_size = 0;
00594             av_log(avctx, AV_LOG_INFO, "No compression.\n");
00595             break;
00596         default:
00597             av_log(avctx, AV_LOG_ERROR, "Unsupported compression format for MSZH (%d).\n", c->compression);
00598             return 1;
00599         }
00600         break;
00601     case CODEC_ID_ZLIB:
00602 #if CONFIG_ZLIB
00603         switch (c->compression) {
00604         case COMP_ZLIB_HISPEED:
00605             av_log(avctx, AV_LOG_INFO, "High speed compression.\n");
00606             break;
00607         case COMP_ZLIB_HICOMP:
00608             av_log(avctx, AV_LOG_INFO, "High compression.\n");
00609             break;
00610         case COMP_ZLIB_NORMAL:
00611             av_log(avctx, AV_LOG_INFO, "Normal compression.\n");
00612             break;
00613         default:
00614             if ((c->compression < Z_NO_COMPRESSION) || (c->compression > Z_BEST_COMPRESSION)) {
00615                 av_log(avctx, AV_LOG_ERROR, "Unsupported compression level for ZLIB: (%d).\n", c->compression);
00616                 return 1;
00617             }
00618             av_log(avctx, AV_LOG_INFO, "Compression level for ZLIB: (%d).\n", c->compression);
00619         }
00620 #else
00621         av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n");
00622         return 1;
00623 #endif
00624         break;
00625     default:
00626         av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in compression switch.\n");
00627         return 1;
00628     }
00629 
00630     /* Allocate decompression buffer */
00631     if (c->decomp_size) {
00632         if ((c->decomp_buf = av_malloc(max_decomp_size)) == NULL) {
00633             av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
00634             return 1;
00635         }
00636     }
00637 
00638     /* Detect flags */
00639     c->flags = *((char *)avctx->extradata + 6);
00640     if (c->flags & FLAG_MULTITHREAD)
00641         av_log(avctx, AV_LOG_INFO, "Multithread encoder flag set.\n");
00642     if (c->flags & FLAG_NULLFRAME)
00643         av_log(avctx, AV_LOG_INFO, "Nullframe insertion flag set.\n");
00644     if ((avctx->codec_id == CODEC_ID_ZLIB) && (c->flags & FLAG_PNGFILTER))
00645         av_log(avctx, AV_LOG_INFO, "PNG filter flag set.\n");
00646     if (c->flags & FLAGMASK_UNUSED)
00647         av_log(avctx, AV_LOG_ERROR, "Unknown flag set (%d).\n", c->flags);
00648 
00649     /* If needed init zlib */
00650     if (avctx->codec_id == CODEC_ID_ZLIB) {
00651 #if CONFIG_ZLIB
00652         c->zstream.zalloc = Z_NULL;
00653         c->zstream.zfree = Z_NULL;
00654         c->zstream.opaque = Z_NULL;
00655         zret = inflateInit(&(c->zstream));
00656         if (zret != Z_OK) {
00657             av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
00658             return 1;
00659         }
00660 #else
00661         av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n");
00662         return 1;
00663 #endif
00664     }
00665 
00666     avctx->pix_fmt = PIX_FMT_BGR24;
00667 
00668     return 0;
00669 }
00670 
00671 /*
00672  *
00673  * Uninit lcl decoder
00674  *
00675  */
00676 static av_cold int decode_end(AVCodecContext *avctx)
00677 {
00678     LclDecContext * const c = avctx->priv_data;
00679 
00680     if (c->pic.data[0])
00681         avctx->release_buffer(avctx, &c->pic);
00682 #if CONFIG_ZLIB
00683     inflateEnd(&(c->zstream));
00684 #endif
00685 
00686     return 0;
00687 }
00688 
00689 #if CONFIG_MSZH_DECODER
00690 AVCodec mszh_decoder = {
00691     "mszh",
00692     CODEC_TYPE_VIDEO,
00693     CODEC_ID_MSZH,
00694     sizeof(LclDecContext),
00695     decode_init,
00696     NULL,
00697     decode_end,
00698     decode_frame,
00699     CODEC_CAP_DR1,
00700     .long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) MSZH"),
00701 };
00702 #endif
00703 
00704 #if CONFIG_ZLIB_DECODER
00705 AVCodec zlib_decoder = {
00706     "zlib",
00707     CODEC_TYPE_VIDEO,
00708     CODEC_ID_ZLIB,
00709     sizeof(LclDecContext),
00710     decode_init,
00711     NULL,
00712     decode_end,
00713     decode_frame,
00714     CODEC_CAP_DR1,
00715     .long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"),
00716 };
00717 #endif

Generated on Sat Feb 16 2013 09:23:12 for ffmpeg by  doxygen 1.7.1