void dometa(u_int meta, u_char *p, u_int len) { switch (meta) { case META_TEXT: case META_COPYRIGHT: case META_TRACK: case META_INSTRUMENT: case META_LYRIC: case META_MARKER: case META_CUE: if (showmeta) { printf("%s: ", metanames[meta]); fwrite(p, len, 1, stdout); printf("\n"); } break; case META_SET_TEMPO: tempo = GET24(p); if (showmeta) printf("Tempo: %d us / quarter note\n", tempo); break; case META_TIMESIGN: if (showmeta) { int n = p[1]; int d = 1; while (n-- > 0) d *= 2; printf("Time signature: %d/%d %d,%d\n", p[0], d, p[2], p[3]); } break; case META_KEY: if (showmeta) printf("Key: %d %s\n", (char)p[0], p[1] ? "minor" : "major"); break; default: break; } }
SANE_Status sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len) { Abaton_Scanner *s = handle; SANE_Status status; uint8_t get_data_status[10]; uint8_t read[10]; uint8_t result[12]; size_t size; SANE_Int data_av = 0; SANE_Int data_length = 0; SANE_Int offset = 0; SANE_Int rread = 0; SANE_Bool Pseudo8bit = SANE_FALSE; *len = 0; /* don't let bogus read requests reach the scanner */ /* this is a sub-optimal way of doing this, I'm sure */ if (!s->scanning) return SANE_STATUS_EOF; if (!strcmp (s->val[OPT_MODE].s, "Gray16")) Pseudo8bit = SANE_TRUE; memset (get_data_status, 0, sizeof (get_data_status)); get_data_status[0] = GET_DATA_STATUS; /* This means "block" for Apple scanners, it seems to be the same for Abaton. The scanner will do non-blocking I/O, but I don't want to go there right now. */ get_data_status[1] = 1; STORE8 (get_data_status + 8, sizeof (result)); memset (read, 0, sizeof (read)); read[0] = READ_10; do { size = sizeof (result); /* this isn't necessary */ /* memset (result, 0, size); */ status = sanei_scsi_cmd (s->fd, get_data_status, sizeof (get_data_status), result, &size); if (status != SANE_STATUS_GOOD) return status; if (!size) { DBG (ERROR_MESSAGE, "sane_read: cannot get_data_status.\n"); return SANE_STATUS_IO_ERROR; } /* this is not an accurate name, but oh well... */ data_length = GET24 (result); data_av = GET24 (result + 9); /* don't check result[3] here, because that screws things up somewhat */ if (data_length) { DBG (IO_MESSAGE, "sane_read: (status) Available in scanner buffer %u.\n", data_av); if (Pseudo8bit) { if ((data_av * 2) + offset > max_len) rread = (max_len - offset) / 2; else rread = data_av; } else if (data_av + offset > max_len) { rread = max_len - offset; } else { rread = data_av; } DBG (IO_MESSAGE, "sane_read: (action) Actual read request for %u bytes.\n", rread); size = rread; STORE24 (read + 6, rread); status = sanei_scsi_cmd (s->fd, read, sizeof (read), buf + offset, &size); if (Pseudo8bit) { SANE_Int byte; SANE_Int pos = offset + (rread << 1) - 1; SANE_Byte B; for (byte = offset + rread - 1; byte >= offset; byte--) { B = buf[byte]; /* don't invert these! */ buf[pos--] = B << 4; /* low (right) nibble */ buf[pos--] = B & 0xF0; /* high (left) nibble */ } /* putting an end to bitop abuse here */ offset += size * 2; } else offset += size; DBG (IO_MESSAGE, "sane_read: Buffer %u of %u full %g%%\n", offset, max_len, (double) (offset * 100. / max_len)); } } while (offset < max_len && data_length != 0 && !s->AbortedByUser); if (s->AbortedByUser) { s->scanning = SANE_FALSE; if (status != SANE_STATUS_GOOD) { DBG (ERROR_MESSAGE, "sane_read: request_sense revealed error: %s\n", sane_strstatus (status)); return status; } status = sanei_scsi_cmd (s->fd, test_unit_ready, sizeof (test_unit_ready), 0, 0); if (status != SANE_STATUS_GOOD || status != SANE_STATUS_INVAL) return status; return SANE_STATUS_CANCELLED; } if (!data_length) { s->scanning = SANE_FALSE; DBG (IO_MESSAGE, "sane_read: (status) No more data..."); if (!offset) { /* this shouldn't happen */ *len = 0; DBG (IO_MESSAGE, "EOF\n"); return SANE_STATUS_EOF; } else { *len = offset; DBG (IO_MESSAGE, "GOOD\n"); return SANE_STATUS_GOOD; } } DBG (FLOW_CONTROL, "sane_read: Normal Exiting, Aborted=%u, data_length=%u\n", s->AbortedByUser, data_av); *len = offset; return SANE_STATUS_GOOD; }