📄 j2g_fiddle.c
字号:
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 + -