⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hpbit_stream_out.c

📁 关于视频压缩的jpeg2000压缩算法,C编写
💻 C
📖 第 1 页 / 共 5 页
字号:
/*****************************************************************************//* Copyright 1998, Hewlett-Packard Company                                   *//* All rights reserved                                                       *//* File: "hpbit_stream_out.c"                                                *//* Description: Reference implementation of the `stream_out' object.         *//* Author: David Taubman                                                     *//* Affiliation: Hewlett-Packard and                                          *//*              The University of New South Wales, Australia                 *//* Acknowledgements: Partly developed in collaboration with Salma Soudagar   *//*                   of Motorola, Switzerland, and her colleagues            *//* Version: VM6.0                                                            *//* Last Revised: 25 January, 2000                                            *//*****************************************************************************//*****************************************************************************//* Modified by David Taubman to avoid the need for byte stuffing when resync *//* markers are in use.  This simplifies the code and substantially improves  *//* the usefulness of the system for applications requiring error resilience. *//* Copyright 1999 by Hewlett-Packard Company with all                        *//* rights reserved for the modified parts.                                   *//*****************************************************************************//*****************************************************************************//* Modified by David Taubman to support interface modifications, arbitrary   *//* changes in coding parameters from component to component and from tile    *//* to tile, to support the full generality of PART-1 of the JPEG2000         *//* standard, and to support most anticipated generality of PART-2.  Changes  *//* are too numerous to flag individually within the code, which in some      *//* places has been completely rewritten.  All changes copyrighted by HP with *//* all rights reserved for the modified parts.                               *//*****************************************************************************//*****************************************************************************//* Modified by Gene Wu to add real markers for COD/COC and QCD/QCC.          *//* All changes copyright 2000 by Ricoh Silicon Valley  with all rights       *//* reserved for the modified parts.                                          *//*****************************************************************************/#include <local_services.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <assert.h>#include <ifc.h>#include <markers.h>#include "hpbit_stream_out_local.h"#include "hpbit_markers.h"/* ========================================================================= *//* ---------------------------- Internal Functions ------------------------- *//* ========================================================================= *//*****************************************************************************//* STATIC                        make_big_endian                             *//*****************************************************************************/static void  make_big_endian(void *buf, int num_words, int precision) /* Use this convenience function to reverse the byte order in words    from which a buffer is constructed, when the current architecture uses    a Little Endian byte order.  The `buf' argument is assumed to    point to a structure consisting of integer-valued fields with 1, 2 or 4    bytes of precision each. */{  int bigendian, n;  std_byte *bp, b0, b1, b2, b3;  bigendian = 1;  bp = (std_byte *)(&bigendian);  *bp = 0;  if (bigendian || (precision == 1))    return;  assert(num_words != 0);  if (precision == 2)    {      for (bp=(std_byte *) buf, n=num_words; n > 0; n--, bp += 2)        {          b0 = bp[0]; b1 = bp[1];          bp[0] = b1; bp[1] = b0;        }    }  else if (precision == 4)    {      for (bp=(std_byte *) buf, n=num_words; n > 0; n--, bp += 4)        {          b0 = bp[0]; b1 = bp[1]; b2 = bp[2]; b3 = bp[3];          bp[0] = b3; bp[1] = b2; bp[2] = b1; bp[3] = b0;        }    }  else    assert(0);}/*****************************************************************************//* STATIC                      copy_to_big_endian                            *//*****************************************************************************/static void  copy_to_big_endian(void *src, void *dst, int num_words, int precision) /* Copies the `src' data to the `dst' data and performs any byte reversal    required to ensure that quantities represented in `dst' have the    Big Endian byte order. */{  int bigendian, n;  std_byte *sp, *dp;  bigendian = 1;  sp = (std_byte *)(&bigendian);  *sp = 0;  if (bigendian || (precision == 1))    {      memcpy(dst,src,num_words*precision);      return;    }  assert(num_words != 0);  if (precision == 2)    {      for (sp=(std_byte *) src, dp=(std_byte *) dst,           n=num_words; n > 0; n--, sp+=2, dp+=2)        {          dp[0] = sp[1];          dp[1] = sp[0];        }    }  else if (precision == 4)    {      for (sp=(std_byte *) src, dp=(std_byte *) dst,           n=num_words; n > 0; n--, sp+=4, dp+=4)        {          dp[0] = sp[3];          dp[1] = sp[2];          dp[2] = sp[1];          dp[3] = sp[0];        }    }  else    assert(0);}/*****************************************************************************//* STATIC                          emit_bytes                                *//*****************************************************************************/static void  emit_bytes(hpbit_stream_out_ref self, std_byte *buf, int num_bytes) /* Emits the indicated bytes directly to the file, up to the limit imposed    by `self->remaining_bytes'.  Byte stuffing, error correction codes, etc.,    should all be handled at a higher level by functions which ultimately    call this function to output the final code stream. */{  self->remaining_bytes -= num_bytes;  if (self->remaining_bytes < 0)    {      num_bytes += self->remaining_bytes;       if (num_bytes <= 0)        return;    }  fwrite(buf,1,(size_t) num_bytes,self->fp);}/*****************************************************************************//* STATIC                          emit_words                                *//*****************************************************************************/static void  emit_words(hpbit_stream_out_ref self, void *buf,             int num_words, int precision) /* Same as `emit_bytes' except that the function emits multi-byte values.    `precision' indicates the number of bytes in each word; it must be    one of 1, 2 or 4.  The function differs from `emit_bytes' in that it    may reorganize the bytes in each word to achieve a consistent BIGENDIAN    byte order (MSB first). */{  make_big_endian(buf,num_words,precision);  emit_bytes(self,(std_byte *) buf,precision*num_words);}/*****************************************************************************//* STATIC                          add_tile                                  *//*****************************************************************************/static hpbit_tile_ptr  add_tile(hpbit_stream_out_ref self, int tnum){  hpbit_tile_ptr tile;  tile = (hpbit_tile_ptr)    local_malloc(HPBIT_MEM_KEY,sizeof(hpbit_tile));  tile->tnum = tnum;  tile->next = self->tiles;  self->tiles = tile;  tile->resync = self->global_resync;  tile->eph = self->global_eph;  return(tile);}/*****************************************************************************//* STATIC                    insert_pre_marker_element                       *//*****************************************************************************/static void  insert_pre_marker_element(hpbit_marker_elt_ptr elt, hpbit_pre_marker_ptr pm) /* Inserts the new element into the list of elements managed by the `pm'    structure, being careful to apply a unique ordering condition to the    marker elements to facilitate later comparison of markers. */{  hpbit_marker_elt_ptr scan, last;  for (last=NULL, scan=pm->elements; scan != NULL; last=scan, scan=scan->next)    if (scan->element_id > elt->element_id)      break;  elt->next = scan;  if (last == NULL)    pm->elements = elt;  else    last->next = elt;}/*****************************************************************************//* STATIC                        destroy_pre_marker                          *//*****************************************************************************/static void  destroy_pre_marker(hpbit_pre_marker_ptr pm){  hpbit_marker_elt_ptr elt;  while ((elt = pm->elements) != NULL)    {      pm->elements = elt->next;      if (elt->buf != NULL)        local_free(elt->buf);      if (elt->set_buf != NULL)        local_free(elt->set_buf);      local_free(elt);    }  local_free(pm);}/*****************************************************************************//* STATIC                   link_connected_pre_markers                       *//*****************************************************************************/static void  link_connected_pre_markers(hpbit_markers_ptr markers) /* This function implements any prior knowledge concerning the    inter-dependence of pre-markers.  The main objective is to ensure that    a marker will be eliminated (as redundant) from a tile-header only if    all dependent markers in the tile-header can simultaneously be    eliminated. */{  hpbit_pre_marker_ptr pm, prev;  /* Process connectedness of COD/COC markers. */  for (prev=NULL, pm=markers->pre_markers; pm != NULL; pm = pm->next)    if ((pm->id == (MARKER_COD & 0x00FF)) ||        (pm->id == (MARKER_COC & 0x00FF)))      {        pm->link_prev = prev;        if (prev != NULL)          prev->link_next = pm;        prev = pm;      }  /* Process connectedness of QCD/QCC markers. */  for (prev=NULL, pm=markers->pre_markers; pm != NULL; pm = pm->next)    if ((pm->id == (MARKER_QCD & 0x00FF)) ||        (pm->id == (MARKER_QCC & 0x00FF)))      {        pm->link_prev = prev;        if (prev != NULL)          prev->link_next = pm;        prev = pm;      }}/*****************************************************************************//* STATIC                     add_codestream_marker                          *//*****************************************************************************/static void  add_codestream_marker(hpbit_markers_ptr markers, void *buf, int length,                        int instance, int place_at_end) /* Use this convenience function to push newly created codestream markers    onto the list (LIFO) referenced from a `markers' structure (there is one    `markers' structure for the global header and one for each tile header.    The contents of the `buf' array are already supposed to contain values    with the correct byte alignment (i.e. big endian).  The `place_at_end'    argument indicates whether the new marker should be placed at the    end or the front of the current list of codestream markers.  This    should be irrelevant for all markers except the CME marker, which is    the only one for which order of appearance in the codestream has    some significance (if there are multiple occurrences of the same    marker with the same Rcme value). */{  hpbit_codestream_marker_ptr elt, last;  elt = (hpbit_codestream_marker_ptr)    local_malloc(HPBIT_MEM_KEY,sizeof(hpbit_codestream_marker));  elt->instance = instance;  elt->num_bytes = length;  elt->buf = buf;  last = markers->codestream_markers;  if (place_at_end && (last != NULL))    {      while (last->next != NULL)        last = last->next;      last->next = elt;    }  else    {      elt->next = markers->codestream_markers;      markers->codestream_markers = elt;    }  markers->total_codestream_bytes += elt->num_bytes;}/*****************************************************************************//* STATIC                 get_tile_component_bands                           *//*****************************************************************************/static int  get_tile_component_bands(hpbit_stream_out_ref self, int tnum, int comp_idx,                           int num_levels) /* This function computes the total number of bands for the relevant    tile-component based on the number of decomposition levels and any    special decomposition structure. */{  int length, hp_descent, num_bands, n;  length = (int)    self->base.size_marker_elt(&(self->base),tnum,MARKER_COC_DECOMP,comp_idx);  if (length == 0)    return(3*num_levels+1); /* Mallat decomposition. */  num_bands = 1;  hp_descent = 0;  for (n=0; n < num_levels; n++)    {      if (n < length)        hp_descent = (int)          self->base.get_marker_val(&(self->base),tnum,MARKER_COC_DECOMP,                                    comp_idx,n);      if (hp_descent == 1)        num_bands += 3;      else if (hp_descent == 2)        num_bands += 12;      else if (hp_descent == 3)        num_bands += 48;      else        num_bands += 3; /* Error; use Mallat as default. */    }        return(num_bands);}/*****************************************************************************//* STATIC                 translate_cod_coc_markers                          */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -