Alien-FreeImage
view release on metacpan or search on metacpan
src/Source/LibJPEG/jmemmgr.c view on Meta::CPAN
LOCAL(void)
do_barray_io (j_common_ptr cinfo, jvirt_barray_ptr ptr, boolean writing)
/* Do backing store read or write of a virtual coefficient-block array */
{
long bytesperrow, file_offset, byte_count, rows, thisrow, i;
bytesperrow = (long) ptr->blocksperrow * SIZEOF(JBLOCK);
file_offset = ptr->cur_start_row * bytesperrow;
/* Loop to read or write each allocation chunk in mem_buffer */
for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) {
/* One chunk, but check for short chunk at end of buffer */
rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i);
/* Transfer no more than is currently defined */
thisrow = (long) ptr->cur_start_row + i;
rows = MIN(rows, (long) ptr->first_undef_row - thisrow);
/* Transfer no more than fits in file */
rows = MIN(rows, (long) ptr->rows_in_array - thisrow);
if (rows <= 0) /* this chunk might be past end of file! */
break;
byte_count = rows * bytesperrow;
if (writing)
(*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info,
(void FAR *) ptr->mem_buffer[i],
file_offset, byte_count);
else
(*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info,
(void FAR *) ptr->mem_buffer[i],
file_offset, byte_count);
file_offset += byte_count;
}
}
METHODDEF(JSAMPARRAY)
access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr,
JDIMENSION start_row, JDIMENSION num_rows,
boolean writable)
/* Access the part of a virtual sample array starting at start_row */
/* and extending for num_rows rows. writable is true if */
/* caller intends to modify the accessed area. */
{
JDIMENSION end_row = start_row + num_rows;
JDIMENSION undef_row;
/* debugging check */
if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess ||
ptr->mem_buffer == NULL)
ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
/* Make the desired part of the virtual array accessible */
if (start_row < ptr->cur_start_row ||
end_row > ptr->cur_start_row+ptr->rows_in_mem) {
if (! ptr->b_s_open)
ERREXIT(cinfo, JERR_VIRTUAL_BUG);
/* Flush old buffer contents if necessary */
if (ptr->dirty) {
do_sarray_io(cinfo, ptr, TRUE);
ptr->dirty = FALSE;
}
/* Decide what part of virtual array to access.
* Algorithm: if target address > current window, assume forward scan,
* load starting at target address. If target address < current window,
* assume backward scan, load so that target area is top of window.
* Note that when switching from forward write to forward read, will have
* start_row = 0, so the limiting case applies and we load from 0 anyway.
*/
if (start_row > ptr->cur_start_row) {
ptr->cur_start_row = start_row;
} else {
/* use long arithmetic here to avoid overflow & unsigned problems */
long ltemp;
ltemp = (long) end_row - (long) ptr->rows_in_mem;
if (ltemp < 0)
ltemp = 0; /* don't fall off front end of file */
ptr->cur_start_row = (JDIMENSION) ltemp;
}
/* Read in the selected part of the array.
* During the initial write pass, we will do no actual read
* because the selected part is all undefined.
*/
do_sarray_io(cinfo, ptr, FALSE);
}
/* Ensure the accessed part of the array is defined; prezero if needed.
* To improve locality of access, we only prezero the part of the array
* that the caller is about to access, not the entire in-memory array.
*/
if (ptr->first_undef_row < end_row) {
if (ptr->first_undef_row < start_row) {
if (writable) /* writer skipped over a section of array */
ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
undef_row = start_row; /* but reader is allowed to read ahead */
} else {
undef_row = ptr->first_undef_row;
}
if (writable)
ptr->first_undef_row = end_row;
if (ptr->pre_zero) {
size_t bytesperrow = (size_t) ptr->samplesperrow * SIZEOF(JSAMPLE);
undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */
end_row -= ptr->cur_start_row;
while (undef_row < end_row) {
FMEMZERO((void FAR *) ptr->mem_buffer[undef_row], bytesperrow);
undef_row++;
}
} else {
if (! writable) /* reader looking at undefined data */
ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
}
}
/* Flag the buffer dirty if caller will write in it */
if (writable)
ptr->dirty = TRUE;
/* Return address of proper part of the buffer */
return ptr->mem_buffer + (start_row - ptr->cur_start_row);
}
METHODDEF(JBLOCKARRAY)
access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr,
JDIMENSION start_row, JDIMENSION num_rows,
boolean writable)
/* Access the part of a virtual block array starting at start_row */
/* and extending for num_rows rows. writable is true if */
/* caller intends to modify the accessed area. */
{
JDIMENSION end_row = start_row + num_rows;
JDIMENSION undef_row;
/* debugging check */
if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess ||
ptr->mem_buffer == NULL)
ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
/* Make the desired part of the virtual array accessible */
if (start_row < ptr->cur_start_row ||
end_row > ptr->cur_start_row+ptr->rows_in_mem) {
if (! ptr->b_s_open)
ERREXIT(cinfo, JERR_VIRTUAL_BUG);
/* Flush old buffer contents if necessary */
if (ptr->dirty) {
do_barray_io(cinfo, ptr, TRUE);
ptr->dirty = FALSE;
}
/* Decide what part of virtual array to access.
* Algorithm: if target address > current window, assume forward scan,
* load starting at target address. If target address < current window,
* assume backward scan, load so that target area is top of window.
* Note that when switching from forward write to forward read, will have
* start_row = 0, so the limiting case applies and we load from 0 anyway.
*/
if (start_row > ptr->cur_start_row) {
ptr->cur_start_row = start_row;
} else {
/* use long arithmetic here to avoid overflow & unsigned problems */
long ltemp;
ltemp = (long) end_row - (long) ptr->rows_in_mem;
if (ltemp < 0)
ltemp = 0; /* don't fall off front end of file */
ptr->cur_start_row = (JDIMENSION) ltemp;
}
/* Read in the selected part of the array.
* During the initial write pass, we will do no actual read
* because the selected part is all undefined.
*/
do_barray_io(cinfo, ptr, FALSE);
}
/* Ensure the accessed part of the array is defined; prezero if needed.
* To improve locality of access, we only prezero the part of the array
* that the caller is about to access, not the entire in-memory array.
*/
if (ptr->first_undef_row < end_row) {
if (ptr->first_undef_row < start_row) {
if (writable) /* writer skipped over a section of array */
ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
undef_row = start_row; /* but reader is allowed to read ahead */
} else {
undef_row = ptr->first_undef_row;
}
if (writable)
ptr->first_undef_row = end_row;
if (ptr->pre_zero) {
size_t bytesperrow = (size_t) ptr->blocksperrow * SIZEOF(JBLOCK);
undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */
end_row -= ptr->cur_start_row;
while (undef_row < end_row) {
FMEMZERO((void FAR *) ptr->mem_buffer[undef_row], bytesperrow);
undef_row++;
}
} else {
if (! writable) /* reader looking at undefined data */
ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
}
}
/* Flag the buffer dirty if caller will write in it */
if (writable)
ptr->dirty = TRUE;
/* Return address of proper part of the buffer */
return ptr->mem_buffer + (start_row - ptr->cur_start_row);
}
/*
* Release all objects belonging to a specified pool.
( run in 1.469 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )