Lines Matching refs:buffer

45  * Read buffer
58 * To accommodate all this, the buffer stores all samples as 16-bit values, even
62 * The read buffer is constructed by a call to buffer_create(), which initializes
63 * the buffer based on width, height, number of colors and depth. The buffer
68 * The buffer maintains read and write pointers.
104 static void buffer_update_read_index(struct Pieusb_Read_Buffer* buffer, int increment);
109 * Initialize the buffer.
112 * @param buffer the buffer to initialize
114 * @param height number of lines in the buffer (pixels in a column)
118 * @param maximum_size maximum size of buffer (-1 = size of image)
122 sanei_pieusb_buffer_create(struct Pieusb_Read_Buffer* buffer, SANE_Int width, SANE_Int height, SANE_Byte color_spec, SANE_Byte depth)
129 buffer->width = width;
130 buffer->height = height;
131 buffer->colors = 0;
132 if (color_spec & 0x01) { buffer->color_index_red = 0; buffer->colors++; } else { buffer->color_index_red = -1; }
133 if (color_spec & 0x02) { buffer->color_index_green = 1; buffer->colors++; } else { buffer->color_index_green = -1; }
134 if (color_spec & 0x04) { buffer->color_index_blue = 2; buffer->colors++; } else { buffer->color_index_blue = -1; }
135 if (color_spec & 0x08) { buffer->color_index_infrared = 3; buffer->colors++; } else { buffer->color_index_infrared = -1; }
136 if (buffer->colors == 0) {
140 buffer->depth = depth;
145 buffer->packing_density = (depth == 1) ? 8 : 1; /* These are all the situations we have */
148 buffer->packet_size_bytes = (buffer->depth * buffer->packing_density + 7) / 8;
149 buffer->line_size_packets = (buffer->width + buffer->packing_density -1) / buffer->packing_density;
150 buffer->line_size_bytes = buffer->line_size_packets * buffer->packet_size_bytes;
151 buffer->image_size_bytes = buffer->colors * buffer->height * buffer->line_size_bytes;
154 snprintf(buffer->buffer_name, L_tmpnam, "/tmp/sane.XXXXXX");
155 if (buffer->data_file != 0) /* might still be open from previous invocation */
156 close(buffer->data_file);
157 buffer->data_file = mkstemp(buffer->buffer_name);
158 if (buffer->data_file == -1) {
159 buffer->data_file = 0;
160 buffer->data = NULL;
161 perror("sanei_pieusb_buffer_create(): error opening image buffer file");
165 buffer_size_bytes = buffer->width * buffer->height * buffer->colors * sizeof(SANE_Uint);
167 close(buffer->data_file);
168 buffer->data_file = 0;
169 DBG(DBG_error, "sanei_pieusb_buffer_create(): buffer_size is zero: width %d, height %d, colors %d\n", buffer->width, buffer->height, buffer->colors);
172 result = lseek(buffer->data_file, buffer_size_bytes-1, SEEK_SET);
174 close(buffer->data_file);
175 buffer->data_file = 0;
176 buffer->data = NULL;
183 result = write(buffer->data_file, &g, 1);
185 close(buffer->data_file);
186 buffer->data_file = 0;
187 buffer->data = NULL;
193 buffer->data = mmap(NULL, buffer_size_bytes, PROT_WRITE | PROT_READ, MAP_SHARED, buffer->data_file, 0);
194 if (buffer->data == MAP_FAILED) {
195 close(buffer->data_file);
196 buffer->data = NULL;
203 buffer->data_size = buffer_size_bytes;
205 buffer->p_read = calloc(buffer->colors, sizeof(SANE_Uint*));
206 if (buffer->p_read == NULL)
208 buffer->p_write = calloc(buffer->colors, sizeof(SANE_Uint*));
209 if (buffer->p_write == NULL)
211 for (k = 0; k < buffer->colors; k++) {
212 buffer->p_write[k] = buffer->data + k * buffer->height * buffer->width;
213 buffer->p_read[k] = buffer->p_write[k];
215 buffer->read_index[0] = 0;
216 buffer->read_index[1] = 0;
217 buffer->read_index[2] = 0;
218 buffer->read_index[3] = 0;
221 buffer->bytes_read = 0;
222 buffer->bytes_written = 0;
223 buffer->bytes_unread = 0;
225 DBG(DBG_info,"pieusb: Read buffer created: w=%d h=%d ncol=%d depth=%d in file %s\n",
226 buffer->width, buffer->height, buffer->colors, buffer->depth, buffer->buffer_name);
231 * Delete buffer and free its resources
233 * @param buffer
236 sanei_pieusb_buffer_delete(struct Pieusb_Read_Buffer* buffer)
239 munmap(buffer->data, buffer->data_size);
243 /* ftruncate(buffer->data_file,0); Can we delete given a file-descriptor? */
244 close(buffer->data_file);
246 unlink(buffer->buffer_name);
247 buffer->data_file = 0;
248 buffer->data_size = 0;
249 free(buffer->p_read);
250 free(buffer->p_write);
251 buffer->data = 0;
252 buffer->width = 0;
253 buffer->height = 0;
254 buffer->depth = 0;
255 buffer->colors = 0;
256 buffer->packing_density = 0;
258 DBG(DBG_info,"pieusb: Read buffer deleted\n");
262 * Add a line to the reader buffer, for the given color.
263 * The buffer checks and decides how to interpret the data.
265 * @param buffer
272 sanei_pieusb_buffer_put_single_color_line(struct Pieusb_Read_Buffer* buffer, SANE_Byte color, void* line, SANE_Int size)
281 c = buffer->color_index_red;
284 c = buffer->color_index_green;
287 c = buffer->color_index_blue;
290 c = buffer->color_index_infrared;
294 DBG(DBG_error, "sanei_pieusb_buffer_put_single_color_line(): color '%c' not specified when buffer was created\n", color);
300 if (buffer->line_size_bytes != size) {
301 DBG(DBG_error, "sanei_pieusb_buffer_put_single_color_line(): incorrect line size, expecting %d, got %d\n", buffer->line_size_bytes, size);
313 if (buffer->packet_size_bytes == 1 && buffer->packing_density == 1) {
317 /* Get next packet data & store in buffer */
318 *buffer->p_write[c]++ = *p_packet++;
321 } else if (buffer->packet_size_bytes == 2 && buffer->packing_density == 1) {
325 /* Get next packet data & store in buffer */
326 *buffer->p_write[c]++ = le16toh (*p_packet++);
331 uint8_t *packet = (uint8_t *)alloca(buffer->packet_size_bytes * sizeof(uint8_t));
333 uint8_t mask = ~(0xFF >> buffer->depth); /* byte with depth most significant bits set */
337 for (k = 0; k < buffer->packet_size_bytes; k++) packet[k] = *p_packet++;
339 * buffer->depth * packing_density <= # bits in packet.
340 * That is checked at buffer creation. */
341 for (k = 0; k < buffer->packing_density; k++) {
343 val = (packet[0] & mask) >> (8-buffer->depth);
345 for (m = 0; m < buffer->packet_size_bytes; m++) {
347 packet[m] <<= buffer->depth;
348 if (m < buffer->packet_size_bytes-1) {
350 packet[m] |= (packet[m+1] >> (8-buffer->depth));
353 /* Store in buffer */
354 *buffer->p_write[c]++ = val;
356 n += buffer->packet_size_bytes;
361 buffer->bytes_written += size;
362 buffer->bytes_unread += size;
364 /* Output current buffer state */
365 /* buffer_output_state(buffer); */
371 * Write line of full color pixels to the buffer.
373 * @param buffer Read buffer
382 sanei_pieusb_buffer_put_full_color_line(struct Pieusb_Read_Buffer* buffer, void* line, int size)
389 if (buffer->line_size_bytes * buffer->colors != size) {
390 DBG(DBG_error, "sanei_pieusb_buffer_put_full_color_line(): incorrect line size, expecting %d, got %d\n", buffer->line_size_bytes * buffer->colors, size);
402 if (buffer->packet_size_bytes == 1 && buffer->packing_density == 1) {
406 /* Get next packet data & store in buffer */
407 for (c = 0; c < buffer->colors; c++) {
408 *buffer->p_write[c]++ = *p_packet++;
412 } else if (buffer->packet_size_bytes == 2 && buffer->packing_density == 1) {
416 /* Get next packet data & store in buffer */
417 for (c = 0; c < buffer->colors; c++) {
418 *buffer->p_write[c]++ = le16toh (*p_packet++);
424 uint8_t *packet = (uint8_t *)alloca(buffer->packet_size_bytes * sizeof(uint8_t));
426 uint8_t mask = ~(0xFF >> buffer->depth); /* byte with depth most significant bits set */
431 for (c = 0; c < buffer->colors; c++) {
432 for (k = 0; k < buffer->packet_size_bytes; k++) {
437 * buffer->depth * packing_density <= # bits in packet.
438 * That is checked at buffer creation. */
439 for (k = 0; k < buffer->packing_density; k++) {
441 val = (packet[0] & mask) >> (8-buffer->depth);
444 for (m = 0; m < buffer->packet_size_bytes; m++) {
446 packet[m] <<= buffer->depth;
448 if (m < buffer->packet_size_bytes-1) {
450 packet[m] |= (packet[m+1] >> (8-buffer->depth));
454 /* Store in buffer */
455 *buffer->p_write[c]++ = val;
457 n += buffer->packet_size_bytes;
463 buffer->bytes_written += size;
464 buffer->bytes_unread += size;
466 /* Output current buffer state */
467 /* buffer_output_state(buffer); */
473 * Return bytes from the buffer. Do not mind pixel boundaries.
478 * @param buffer Buffer to return bytes from.
484 sanei_pieusb_buffer_get(struct Pieusb_Read_Buffer* buffer, SANE_Byte* data, SANE_Int max_len, SANE_Int* len)
494 N = buffer->width * buffer->height;
496 if (buffer->packet_size_bytes == 1 && buffer->packing_density == 1) {
497 /* Single byte values in buffer */
498 while (n < max_len && buffer->bytes_read < buffer->image_size_bytes) {
500 *pdata++ = *(buffer->data + N*buffer->read_index[0] + buffer->width*buffer->read_index[1] + buffer->read_index[2]) & 0xFF;
502 buffer_update_read_index(buffer,1);
504 buffer->bytes_read++;
507 } else if (buffer->packet_size_bytes == 1 && buffer->packing_density == 8) {
508 /* Unpacked bits in buffer: repack */
509 while (n < max_len && buffer->bytes_read < buffer->image_size_bytes) {
513 if (buffer->width - buffer->read_index[2] < 8) {
514 n_bits = buffer->width - buffer->read_index[2];
518 if (*(buffer->data + N*buffer->read_index[0] + buffer->width*buffer->read_index[1] + buffer->read_index[2] + i) > 0) {
525 buffer_update_read_index(buffer,n_bits);
527 buffer->bytes_read++;
530 } else if (buffer->packet_size_bytes == 2) {
531 /* Two-byte values in buffer */
532 while (n < max_len && buffer->bytes_read < buffer->image_size_bytes) {
534 SANE_Uint val = *(buffer->data + N*buffer->read_index[0] + buffer->width*buffer->read_index[1] + buffer->read_index[2]);
536 if (buffer->read_index[3] == 0) {
542 buffer_update_read_index(buffer,1);
544 buffer->bytes_read++;
549 DBG(DBG_error, "buffer_put(): paccket size & density of %d/%d not implemented\n", buffer->packet_size_bytes, buffer->packing_density);
555 buffer->bytes_unread -= n;
557 /* Output current buffer state */
558 /* buffer_output_state(buffer); */
564 * @param buffer the buffer to initialize
567 static void buffer_update_read_index(struct Pieusb_Read_Buffer* buffer, int increment)
574 if (buffer->read_index[3] == 0 && buffer->packet_size_bytes == 2) {
575 buffer->read_index[3] = 1;
577 buffer->read_index[3] = 0;
578 buffer->read_index[0]++;
579 if (buffer->read_index[0] == buffer->colors) {
580 buffer->read_index[0] = 0;
581 buffer->read_index[2] += increment;
582 if (buffer->read_index[2] >= buffer->width) {
583 buffer->read_index[2] = 0;
584 buffer->read_index[1]++;
592 * Display the buffer state.
594 * @param buffer the buffer to initialize
597 static void buffer_output_state(struct Pieusb_Read_Buffer* buffer)
602 line_size = buffer->line_size_bytes * buffer->colors; /* Full line size in bytes */
605 DBG(DBG_info_buffer," width/height/colors/depth = %d %d %d %d (buffer size %d)\n",
606 buffer->width, buffer->height, buffer->colors, buffer->depth, buffer->image_size_bytes);
609 N = buffer->width * buffer->height;
610 for (k = 0; k < buffer->colors; k++) {
611 loc[k] = buffer->p_read[k] - buffer->data - k*N;
613 for (k = buffer->colors; k < 4; k++) {
617 for (k = 0; k < buffer->colors; k++) {
618 loc[k] = buffer->p_write[k] - buffer->data - k*N;
620 for (k = buffer->colors; k < 4; k++) {
626 double fdata = (double)buffer->bytes_unread/buffer->image_size_bytes*100;
627 double fread = (double)buffer->bytes_read/buffer->image_size_bytes*100;
628 double fwritten = (double)buffer->bytes_written/buffer->image_size_bytes*100;
630 buffer->image_size_bytes, buffer->bytes_unread, fdata, buffer->bytes_read, fread, buffer->bytes_written, fwritten);
632 (double)buffer->image_size_bytes/line_size, (double)buffer->bytes_unread/line_size, (double)buffer->bytes_read/line_size, (double)buffer->bytes_written/line_size);