LCOV - code coverage report
Current view: directory - media/libjpeg - jcmainct.c (source / functions) Found Hit Coverage
Test: app.info Lines: 45 34 75.6 %
Date: 2012-06-02 Functions: 3 3 100.0 %

       1                 : /*
       2                 :  * jcmainct.c
       3                 :  *
       4                 :  * Copyright (C) 1994-1996, Thomas G. Lane.
       5                 :  * This file is part of the Independent JPEG Group's software.
       6                 :  * For conditions of distribution and use, see the accompanying README file.
       7                 :  *
       8                 :  * This file contains the main buffer controller for compression.
       9                 :  * The main buffer lies between the pre-processor and the JPEG
      10                 :  * compressor proper; it holds downsampled data in the JPEG colorspace.
      11                 :  */
      12                 : 
      13                 : #define JPEG_INTERNALS
      14                 : #include "jinclude.h"
      15                 : #include "jpeglib.h"
      16                 : 
      17                 : 
      18                 : /* Note: currently, there is no operating mode in which a full-image buffer
      19                 :  * is needed at this step.  If there were, that mode could not be used with
      20                 :  * "raw data" input, since this module is bypassed in that case.  However,
      21                 :  * we've left the code here for possible use in special applications.
      22                 :  */
      23                 : #undef FULL_MAIN_BUFFER_SUPPORTED
      24                 : 
      25                 : 
      26                 : /* Private buffer controller object */
      27                 : 
      28                 : typedef struct {
      29                 :   struct jpeg_c_main_controller pub; /* public fields */
      30                 : 
      31                 :   JDIMENSION cur_iMCU_row;      /* number of current iMCU row */
      32                 :   JDIMENSION rowgroup_ctr;      /* counts row groups received in iMCU row */
      33                 :   boolean suspended;            /* remember if we suspended output */
      34                 :   J_BUF_MODE pass_mode;         /* current operating mode */
      35                 : 
      36                 :   /* If using just a strip buffer, this points to the entire set of buffers
      37                 :    * (we allocate one for each component).  In the full-image case, this
      38                 :    * points to the currently accessible strips of the virtual arrays.
      39                 :    */
      40                 :   JSAMPARRAY buffer[MAX_COMPONENTS];
      41                 : 
      42                 : #ifdef FULL_MAIN_BUFFER_SUPPORTED
      43                 :   /* If using full-image storage, this array holds pointers to virtual-array
      44                 :    * control blocks for each component.  Unused if not full-image storage.
      45                 :    */
      46                 :   jvirt_sarray_ptr whole_image[MAX_COMPONENTS];
      47                 : #endif
      48                 : } my_main_controller;
      49                 : 
      50                 : typedef my_main_controller * my_main_ptr;
      51                 : 
      52                 : 
      53                 : /* Forward declarations */
      54                 : METHODDEF(void) process_data_simple_main
      55                 :         JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf,
      56                 :              JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail));
      57                 : #ifdef FULL_MAIN_BUFFER_SUPPORTED
      58                 : METHODDEF(void) process_data_buffer_main
      59                 :         JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf,
      60                 :              JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail));
      61                 : #endif
      62                 : 
      63                 : 
      64                 : /*
      65                 :  * Initialize for a processing pass.
      66                 :  */
      67                 : 
      68                 : METHODDEF(void)
      69               3 : start_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
      70                 : {
      71               3 :   my_main_ptr main_ptr = (my_main_ptr) cinfo->main;
      72                 : 
      73                 :   /* Do nothing in raw-data mode. */
      74               3 :   if (cinfo->raw_data_in)
      75               0 :     return;
      76                 : 
      77               3 :   main_ptr->cur_iMCU_row = 0;        /* initialize counters */
      78               3 :   main_ptr->rowgroup_ctr = 0;
      79               3 :   main_ptr->suspended = FALSE;
      80               3 :   main_ptr->pass_mode = pass_mode;   /* save mode for use by process_data */
      81                 : 
      82               3 :   switch (pass_mode) {
      83                 :   case JBUF_PASS_THRU:
      84                 : #ifdef FULL_MAIN_BUFFER_SUPPORTED
      85                 :     if (main_ptr->whole_image[0] != NULL)
      86                 :       ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
      87                 : #endif
      88               3 :     main_ptr->pub.process_data = process_data_simple_main;
      89               3 :     break;
      90                 : #ifdef FULL_MAIN_BUFFER_SUPPORTED
      91                 :   case JBUF_SAVE_SOURCE:
      92                 :   case JBUF_CRANK_DEST:
      93                 :   case JBUF_SAVE_AND_PASS:
      94                 :     if (main_ptr->whole_image[0] == NULL)
      95                 :       ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
      96                 :     main_ptr->pub.process_data = process_data_buffer_main;
      97                 :     break;
      98                 : #endif
      99                 :   default:
     100               0 :     ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
     101               0 :     break;
     102                 :   }
     103                 : }
     104                 : 
     105                 : 
     106                 : /*
     107                 :  * Process some data.
     108                 :  * This routine handles the simple pass-through mode,
     109                 :  * where we have only a strip buffer.
     110                 :  */
     111                 : 
     112                 : METHODDEF(void)
     113             144 : process_data_simple_main (j_compress_ptr cinfo,
     114                 :                           JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
     115                 :                           JDIMENSION in_rows_avail)
     116                 : {
     117             144 :   my_main_ptr main_ptr = (my_main_ptr) cinfo->main;
     118                 : 
     119             306 :   while (main_ptr->cur_iMCU_row < cinfo->total_iMCU_rows) {
     120                 :     /* Read input data if we haven't filled the main buffer yet */
     121             159 :     if (main_ptr->rowgroup_ctr < DCTSIZE)
     122             159 :       (*cinfo->prep->pre_process_data) (cinfo,
     123                 :                                         input_buf, in_row_ctr, in_rows_avail,
     124                 :                                         main_ptr->buffer, &main_ptr->rowgroup_ctr,
     125                 :                                         (JDIMENSION) DCTSIZE);
     126                 : 
     127                 :     /* If we don't have a full iMCU row buffered, return to application for
     128                 :      * more data.  Note that preprocessor will always pad to fill the iMCU row
     129                 :      * at the bottom of the image.
     130                 :      */
     131             159 :     if (main_ptr->rowgroup_ctr != DCTSIZE)
     132             141 :       return;
     133                 : 
     134                 :     /* Send the completed row to the compressor */
     135              18 :     if (! (*cinfo->coef->compress_data) (cinfo, main_ptr->buffer)) {
     136                 :       /* If compressor did not consume the whole row, then we must need to
     137                 :        * suspend processing and return to the application.  In this situation
     138                 :        * we pretend we didn't yet consume the last input row; otherwise, if
     139                 :        * it happened to be the last row of the image, the application would
     140                 :        * think we were done.
     141                 :        */
     142               0 :       if (! main_ptr->suspended) {
     143               0 :         (*in_row_ctr)--;
     144               0 :         main_ptr->suspended = TRUE;
     145                 :       }
     146               0 :       return;
     147                 :     }
     148                 :     /* We did finish the row.  Undo our little suspension hack if a previous
     149                 :      * call suspended; then mark the main buffer empty.
     150                 :      */
     151              18 :     if (main_ptr->suspended) {
     152               0 :       (*in_row_ctr)++;
     153               0 :       main_ptr->suspended = FALSE;
     154                 :     }
     155              18 :     main_ptr->rowgroup_ctr = 0;
     156              18 :     main_ptr->cur_iMCU_row++;
     157                 :   }
     158                 : }
     159                 : 
     160                 : 
     161                 : #ifdef FULL_MAIN_BUFFER_SUPPORTED
     162                 : 
     163                 : /*
     164                 :  * Process some data.
     165                 :  * This routine handles all of the modes that use a full-size buffer.
     166                 :  */
     167                 : 
     168                 : METHODDEF(void)
     169                 : process_data_buffer_main (j_compress_ptr cinfo,
     170                 :                           JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
     171                 :                           JDIMENSION in_rows_avail)
     172                 : {
     173                 :   my_main_ptr main = (my_main_ptr) cinfo->main;
     174                 :   int ci;
     175                 :   jpeg_component_info *compptr;
     176                 :   boolean writing = (main_ptr->pass_mode != JBUF_CRANK_DEST);
     177                 : 
     178                 :   while (main_ptr->cur_iMCU_row < cinfo->total_iMCU_rows) {
     179                 :     /* Realign the virtual buffers if at the start of an iMCU row. */
     180                 :     if (main_ptr->rowgroup_ctr == 0) {
     181                 :       for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
     182                 :            ci++, compptr++) {
     183                 :         main_ptr->buffer[ci] = (*cinfo->mem->access_virt_sarray)
     184                 :           ((j_common_ptr) cinfo, main_ptr->whole_image[ci],
     185                 :            main_ptr->cur_iMCU_row * (compptr->v_samp_factor * DCTSIZE),
     186                 :            (JDIMENSION) (compptr->v_samp_factor * DCTSIZE), writing);
     187                 :       }
     188                 :       /* In a read pass, pretend we just read some source data. */
     189                 :       if (! writing) {
     190                 :         *in_row_ctr += cinfo->max_v_samp_factor * DCTSIZE;
     191                 :         main_ptr->rowgroup_ctr = DCTSIZE;
     192                 :       }
     193                 :     }
     194                 : 
     195                 :     /* If a write pass, read input data until the current iMCU row is full. */
     196                 :     /* Note: preprocessor will pad if necessary to fill the last iMCU row. */
     197                 :     if (writing) {
     198                 :       (*cinfo->prep->pre_process_data) (cinfo,
     199                 :                                         input_buf, in_row_ctr, in_rows_avail,
     200                 :                                         main_ptr->buffer, &main_ptr->rowgroup_ctr,
     201                 :                                         (JDIMENSION) DCTSIZE);
     202                 :       /* Return to application if we need more data to fill the iMCU row. */
     203                 :       if (main_ptr->rowgroup_ctr < DCTSIZE)
     204                 :         return;
     205                 :     }
     206                 : 
     207                 :     /* Emit data, unless this is a sink-only pass. */
     208                 :     if (main_ptr->pass_mode != JBUF_SAVE_SOURCE) {
     209                 :       if (! (*cinfo->coef->compress_data) (cinfo, main_ptr->buffer)) {
     210                 :         /* If compressor did not consume the whole row, then we must need to
     211                 :          * suspend processing and return to the application.  In this situation
     212                 :          * we pretend we didn't yet consume the last input row; otherwise, if
     213                 :          * it happened to be the last row of the image, the application would
     214                 :          * think we were done.
     215                 :          */
     216                 :         if (! main_ptr->suspended) {
     217                 :           (*in_row_ctr)--;
     218                 :           main_ptr->suspended = TRUE;
     219                 :         }
     220                 :         return;
     221                 :       }
     222                 :       /* We did finish the row.  Undo our little suspension hack if a previous
     223                 :        * call suspended; then mark the main buffer empty.
     224                 :        */
     225                 :       if (main_ptr->suspended) {
     226                 :         (*in_row_ctr)++;
     227                 :         main_ptr->suspended = FALSE;
     228                 :       }
     229                 :     }
     230                 : 
     231                 :     /* If get here, we are done with this iMCU row.  Mark buffer empty. */
     232                 :     main_ptr->rowgroup_ctr = 0;
     233                 :     main_ptr->cur_iMCU_row++;
     234                 :   }
     235                 : }
     236                 : 
     237                 : #endif /* FULL_MAIN_BUFFER_SUPPORTED */
     238                 : 
     239                 : 
     240                 : /*
     241                 :  * Initialize main buffer controller.
     242                 :  */
     243                 : 
     244                 : GLOBAL(void)
     245               3 : jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer)
     246                 : {
     247                 :   my_main_ptr main_ptr;
     248                 :   int ci;
     249                 :   jpeg_component_info *compptr;
     250                 : 
     251               3 :   main_ptr = (my_main_ptr)
     252               3 :     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
     253                 :                                 SIZEOF(my_main_controller));
     254               3 :   cinfo->main = (struct jpeg_c_main_controller *) main_ptr;
     255               3 :   main_ptr->pub.start_pass = start_pass_main;
     256                 : 
     257                 :   /* We don't need to create a buffer in raw-data mode. */
     258               3 :   if (cinfo->raw_data_in)
     259               0 :     return;
     260                 : 
     261                 :   /* Create the buffer.  It holds downsampled data, so each component
     262                 :    * may be of a different size.
     263                 :    */
     264               3 :   if (need_full_buffer) {
     265                 : #ifdef FULL_MAIN_BUFFER_SUPPORTED
     266                 :     /* Allocate a full-image virtual array for each component */
     267                 :     /* Note we pad the bottom to a multiple of the iMCU height */
     268                 :     for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
     269                 :          ci++, compptr++) {
     270                 :       main_ptr->whole_image[ci] = (*cinfo->mem->request_virt_sarray)
     271                 :         ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
     272                 :          compptr->width_in_blocks * DCTSIZE,
     273                 :          (JDIMENSION) jround_up((long) compptr->height_in_blocks,
     274                 :                                 (long) compptr->v_samp_factor) * DCTSIZE,
     275                 :          (JDIMENSION) (compptr->v_samp_factor * DCTSIZE));
     276                 :     }
     277                 : #else
     278               0 :     ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
     279                 : #endif
     280                 :   } else {
     281                 : #ifdef FULL_MAIN_BUFFER_SUPPORTED
     282                 :     main_ptr->whole_image[0] = NULL; /* flag for no virtual arrays */
     283                 : #endif
     284                 :     /* Allocate a strip buffer for each component */
     285              15 :     for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
     286               9 :          ci++, compptr++) {
     287              18 :       main_ptr->buffer[ci] = (*cinfo->mem->alloc_sarray)
     288              27 :         ((j_common_ptr) cinfo, JPOOL_IMAGE,
     289               9 :          compptr->width_in_blocks * DCTSIZE,
     290               9 :          (JDIMENSION) (compptr->v_samp_factor * DCTSIZE));
     291                 :     }
     292                 :   }
     293                 : }

Generated by: LCOV version 1.7