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

📄 j2g_fiddle.c

📁 JPEG2000实现的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
  eoc[0] = 0xFF;
  eoc[1] = (MARKER_EOC & 0x00FF);
  fwrite(eoc,1,2,fp);
}

/*****************************************************************************/
/* STATIC                    update_tilepart_length                          */
/*****************************************************************************/

static void
  update_tilepart_length(j2g_tilepart_ptr tp)

 /* Updates the Lsot field in the tile-part's SOT marker to reflect
    the tile-length field in the `tp' structure.  This function should
    be called whenever an operation is performed which changes the total
    number of bytes in the tile-part. */

{
  j2g_marker_ptr sot;

  sot = tp->markers;
  assert(sot->marker_code == MARKER_SOT);
  sot->buf[6] = (std_byte)((tp->tile_length >> 24) & 0x000000FF);
  sot->buf[7] = (std_byte)((tp->tile_length >> 16) & 0x000000FF);
  sot->buf[8] = (std_byte)((tp->tile_length >> 8) & 0x000000FF);
  sot->buf[9] = (std_byte)((tp->tile_length >> 0) & 0x000000FF);
}

/*****************************************************************************/
/* STATIC                     process_in_data_markers                        */
/*****************************************************************************/

static void
  process_in_data_markers(j2g_codestream_ptr codestream,
                          int discard_eph, int discard_sop)
{
  j2g_marker_ptr scan;
  j2g_tilepart_ptr tp;
  j2g_packet_ptr packet;
  std_byte mask;

  mask = 0xFF;
  if (discard_eph)
    mask &= ~4;
  if (discard_sop)
    mask &= ~2;
  for (scan=codestream->global_markers; scan != NULL; scan=scan->next)
    if (scan->marker_code == MARKER_COD)
      {
        if (scan->total_bytes <  5)
          local_error("The COD marker segment is too short!!");
        scan->buf[4] &= mask;
      }
  for (tp=codestream->tileparts; tp != NULL; tp=tp->next)
    {
      int discarded_bytes, n;
      
      if (discard_eph)
        tp->uses_eph = 0;
      if (discard_sop)
        tp->uses_resync = 0;
      for (scan=tp->markers; scan != NULL; scan=scan->next)
        if (scan->marker_code == MARKER_COD)
          {
            if (scan->total_bytes <  5)
              local_error("The COD marker segment is too short!!");
            scan->buf[4] &= mask;
          }
      discarded_bytes = 0;
      for (packet=tp->packets; packet != NULL; packet=packet->next)
        {
          if (discard_sop)
            {
              packet->buf += 6;
              packet->packet_bytes -= 6;
              if (packet->head_bytes)
                packet->head_bytes -= 6;
              discarded_bytes += 6;
            }
          if (discard_eph && (packet->head_bytes > 2))
            {
              packet->head_bytes -= 2;
              packet->packet_bytes -= 2;
              discarded_bytes += 2;
              for (n=packet->head_bytes; n < packet->packet_bytes; n++)
                packet->buf[n] = packet->buf[n+2];
            }
        }
      tp->tile_length -= discarded_bytes;
      update_tilepart_length(tp);
    }
}

/*****************************************************************************/
/* STATIC                     partition_into_tileparts                       */
/*****************************************************************************/

static void
  partition_into_tileparts(j2g_codestream_ptr codestream, int max_packets)

 /* Note: this code simply won't work if there are PPT/PPM packet packet
    header markers or if there are PLT/PLM pointer markers.  It also will
    not work if the codestream initially contains multiple tile-parts
    per tile. */

{
  j2g_tilepart_ptr tp, last_tp, new_tp, first;
  j2g_packet_ptr pscan, last_pscan;
  j2g_marker_ptr mscan;
  int bytes_left, n;

  if (codestream->tileparts == NULL)
    return;
  if (codestream->total_tileparts != codestream->total_tiles)
    local_error("Cannot currently partition input codestream which already "
                "contain partitioned tiles.");
  last_tp = codestream->tileparts;
  while (last_tp->next != NULL)
    last_tp = last_tp->next;
  for (tp=codestream->tileparts; tp != NULL; tp = tp->next)
    if (tp->num_packets > max_packets)
      {
        int old_sot;

        old_sot = 0;
        if (tp->num_tparts == 0)
          {
            tp->num_tparts = 1;
            old_sot = 1;
          }
        assert(tp->tpart == 0);
        if (tp->num_tparts > 1)
          local_error("Erroneous `NTPsot' field in SOT marker!");
        first = tp;
        while (tp->num_packets > max_packets)
          {
            codestream->total_tileparts++;
            new_tp = (j2g_tilepart_ptr)
              local_malloc("FIDDLE",sizeof(j2g_tilepart));
            new_tp->next = NULL;
            last_tp->next = new_tp;
            last_tp = new_tp;
            new_tp->tnum = tp->tnum;
            new_tp->tpart = first->num_tparts++;
            new_tp->uses_eph = first->uses_eph;
            new_tp->uses_resync = first->uses_resync;
            if (first->num_tparts > 255)
              local_error("Cannot split a tile into more than 255 "
                          "tile-parts!");
            new_tp->num_tparts = 0;
            for (bytes_left=0, last_pscan=NULL, pscan=tp->packets,
                 n=0; n < max_packets; n++,
                 last_pscan=pscan, pscan = pscan->next)
              bytes_left += pscan->packet_bytes;
            for (mscan=tp->markers; mscan != NULL; mscan=mscan->next)
              bytes_left += mscan->total_bytes;
            last_pscan->next = NULL;
            new_tp->packets = pscan;
            new_tp->num_packets = tp->num_packets - max_packets;
            tp->num_packets = max_packets;
            new_tp->tile_length = tp->tile_length - bytes_left;
            tp->tile_length = bytes_left;
            new_tp->tile_length += 14-old_sot;
            
            /* Now create SOT and SOD markers for the new tilepart. */

            mscan = (j2g_marker_ptr) local_malloc("FIDDLE",sizeof(j2g_marker));
            new_tp->markers = mscan;
            mscan->marker_code = MARKER_SOT;
            mscan->buf = mscan->buf_handle = (std_byte *)
              local_malloc("FIDDLE",12);
            mscan->total_bytes = 12-old_sot;
            mscan->buf[0] = 0xFF;
            mscan->buf[1] = (MARKER_SOT & 0x00FF);
            mscan->buf[2] = 0;
            mscan->buf[3] = (old_sot)?9:10;
            mscan->buf[4] = first->markers->buf[4];
            mscan->buf[5] = first->markers->buf[5];
            mscan->buf[10] = (std_byte) new_tp->tpart;
            mscan->buf[11] = 0;
            mscan = mscan->next = (j2g_marker_ptr)
              local_malloc("FIDDLE",sizeof(j2g_marker));
            mscan->marker_code = MARKER_SOD;
            mscan->next = NULL;
            mscan->buf = mscan->buf_handle = (std_byte *)
              local_malloc("FIDDLE",2);
            mscan->total_bytes = 2;
            mscan->next = NULL;
            mscan->buf[0] = 0xFF;
            mscan->buf[1] = (MARKER_SOD & 0x00FF);
            update_tilepart_length(new_tp);
            update_tilepart_length(tp);
            tp = new_tp;
          }

        tp = first;
        if (!old_sot)
          {
            assert(tp->markers->total_bytes > 11);
            tp->markers->buf[11] = (std_byte)(tp->num_tparts);
          }
      }
}

/*****************************************************************************/
/* STATIC                          add_ppt_marker                            */
/*****************************************************************************/

static void
  add_ppt_marker(j2g_tilepart_ptr tp, std_byte *buf, int buf_bytes,
                 std_byte Zppt)

 /* The `buf' array contains `buf_bytes' bytes of packet head bytes to
    pack into a new PPT marker. */

{
  j2g_marker_ptr marker;
  int marker_bytes, Lppt;
  std_byte *bp;

  marker_bytes = buf_bytes + 5;
  tp->tile_length += marker_bytes;
  Lppt = marker_bytes - 2;
  marker = (j2g_marker_ptr)
    local_malloc("FIDDLE",sizeof(j2g_marker));
  marker->marker_code = MARKER_PPT;
  marker->total_bytes = marker_bytes;
  marker->buf = marker->buf_handle = bp = (std_byte *)
    local_malloc("FIDDLE",marker_bytes);
  *(bp++) = 0xFF;
  *(bp++) = (std_byte)(MARKER_PPT & 0x00FF);
  *(bp++) = (std_byte)((Lppt >> 8) & 0x00FF);
  *(bp++) = (std_byte)((Lppt >> 0) & 0x00FF);
  *(bp++) = Zppt;
  memcpy(bp,buf,(size_t) buf_bytes);

  /* Now insert immediately after the SOT marker. */
  assert(tp->markers != NULL);
  marker->next = tp->markers->next;
  tp->markers->next = marker;
}

/*****************************************************************************/
/* STATIC                          add_ppm_marker                            */
/*****************************************************************************/

/* Begin DST PPM fix */
static void
  add_ppm_marker(j2g_codestream_ptr stream, std_byte *buf, int buf_bytes,
                 std_byte Zppm)

 /* The `buf' array contains `buf_bytes' bytes of tile-part length and
    packet head bytes to pack into a new PPM marker. */

{
  j2g_marker_ptr marker;
  int marker_bytes, Lppt;
  std_byte *bp;

  marker_bytes = buf_bytes + 5;
  Lppt = marker_bytes - 2;
  marker = (j2g_marker_ptr)
    local_malloc("FIDDLE",sizeof(j2g_marker));
  marker->marker_code = MARKER_PPM;
  marker->total_bytes = marker_bytes;
  marker->buf = marker->buf_handle = bp = (std_byte *)
    local_malloc("FIDDLE",marker_bytes);
  *(bp++) = 0xFF;
  *(bp++) = (std_byte)(MARKER_PPM & 0x00FF);
  *(bp++) = (std_byte)((Lppt >> 8) & 0x00FF);
  *(bp++) = (std_byte)((Lppt >> 0) & 0x00FF);
  *(bp++) = Zppm;
  memcpy(bp,buf,(size_t) buf_bytes);

  /* Now insert immediately after the SOC marker. */
  assert(stream->global_markers != NULL);
  marker->next = stream->global_markers->next;
  stream->global_markers->next = marker;
}
/* End DST PPM fix */

/*****************************************************************************/
/* STATIC                         make_ppt_markers                           */
/*****************************************************************************/

static void
  make_ppt_markers(j2g_codestream_ptr codestream, int max_bytes)
{
  j2g_tilepart_ptr tp;
  j2g_packet_ptr packet;
  std_byte *buf, *bp, Zppt;
  int buf_bytes, head_bytes;

  if (max_bytes > (1<<16))
    max_bytes = (1<<16);
  if (max_bytes < 6)
    local_error("Non-empty PPT markers must have at least 6 bytes each!  "
                "You must supply a larger parameter to the `-make_ppt' "
                "argument!");
  max_bytes -= 5;
  buf = (std_byte *) local_malloc("FIDDLE",max_bytes);
  for (tp=codestream->tileparts; tp != NULL; tp = tp->next)
    {
      if (tp->packets == NULL)
        continue;
      buf_bytes = 0;
      Zppt = 0;
      bp = buf;
      for (packet=tp->packets; packet != NULL; packet = packet->next)
        {
          head_bytes = packet->head_bytes;
          if (head_bytes <= 0)
            local_error("Cannot generate PPT markers for the current "
                        "codestream!  You need to include EPH markers when "
                        "generating the original codestream, using the "
                        "`-Beph' option with the VM's compressor!");
          if (tp->uses_resync)
            head_bytes -= 6;
          assert(head_bytes > 0);
          if ((buf_bytes + head_bytes) > max_bytes)
            { /* Create new PPT marker. */
              if (buf_bytes > 0)
                add_ppt_marker(tp,buf,buf_bytes,Zppt++);
              buf_bytes = 0;
              bp = buf;
              if (max_bytes < head_bytes)
                local_error("You have restricted PPT markers to be so small "
                            "that it is not possible to avoid fragmenting "
                            "one of the packet headers across multiple PPT "
                            "markers!  You should specify a larger parameter "
                            "with the `-make_ppt' argument!");
            }
          tp->tile_length -= head_bytes;
          packet->packet_bytes -= head_bytes;
          if (tp->uses_resync)
            packet->buf += 6;
          for (; head_bytes > 0; head_bytes--, buf_bytes++)
            *(bp++) = *(packet->buf++);
          if (tp->uses_resync)
            {
              head_bytes = packet->head_bytes;
              packet->buf[-1] = packet->buf[-head_bytes+5];
              packet->buf[-2] = packet->buf[-head_bytes+4];
              packet->buf[-3] = packet->buf[-head_bytes+3];
              packet->buf[-4] = packet->buf[-head_bytes+2];
              packet->buf[-5] = packet->buf[-head_bytes+1];
              packet->buf[-6] = packet->buf[-head_bytes+0];
              packet->buf -= 6;
              assert((packet->buf[0] == 0xFF) &&
                     (packet->buf[1] == (std_byte)(MARKER_SOP & 0x00FF)));

⌨️ 快捷键说明

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