static SANE_Status request_sense (Abaton_Scanner * s) { uint8_t cmd[6]; uint8_t result[22]; size_t size = sizeof (result); SANE_Status status; memset (cmd, 0, sizeof (cmd)); memset (result, 0, sizeof (result)); cmd[0] = REQUEST_SENSE; STORE8 (cmd + 4, sizeof (result)); sanei_scsi_cmd (s->fd, cmd, sizeof (cmd), result, &size); if (result[7] != 14) { DBG (ERROR_MESSAGE, "Additional Length %u\n", (unsigned int) result[7]); status = SANE_STATUS_IO_ERROR; } status = sense_handler (s->fd, result, NULL); if (status == SANE_STATUS_IO_ERROR) { /* Since I haven't figured out the vendor unique error codes on this thing, I'll just handle the normal ones for now */ if (result[18] & 0x80) DBG (ERROR_MESSAGE, "Sense: Dim Light (output of lamp below 70%%).\n"); if (result[18] & 0x40) DBG (ERROR_MESSAGE, "Sense: No Light at all.\n"); if (result[18] & 0x20) DBG (ERROR_MESSAGE, "Sense: No Home.\n"); if (result[18] & 0x10) DBG (ERROR_MESSAGE, "Sense: No Limit. Tried to scan out of range.\n"); } DBG (USER_MESSAGE, "Sense: Optical gain %u.\n", (unsigned int) result[20]); return status; }
/* Process 2OPI Integer instructions */ bool eval_2OPI_Int(struct lilith* vm, struct Instruction* c) { #ifdef DEBUG char Name[20] = "ILLEGAL_2OPI"; #endif /* 0x0E ... 0x2B */ /* 0xB0 ... 0xDF */ switch(c->raw2) { case 0x0E: /* ADDI */ { #ifdef DEBUG strncpy(Name, "ADDI", 19); #elif TRACE record_trace("ADDI"); #endif ADDI(vm, c); break; } case 0x0F: /* ADDUI */ { #ifdef DEBUG strncpy(Name, "ADDUI", 19); #elif TRACE record_trace("ADDUI"); #endif ADDUI(vm, c); break; } case 0x10: /* SUBI */ { #ifdef DEBUG strncpy(Name, "SUBI", 19); #elif TRACE record_trace("SUBI"); #endif SUBI(vm, c); break; } case 0x11: /* SUBUI */ { #ifdef DEBUG strncpy(Name, "SUBUI", 19); #elif TRACE record_trace("SUBUI"); #endif SUBUI(vm, c); break; } case 0x12: /* CMPI */ { #ifdef DEBUG strncpy(Name, "CMPI", 19); #elif TRACE record_trace("CMPI"); #endif CMPI(vm, c); break; } case 0x13: /* LOAD */ { #ifdef DEBUG strncpy(Name, "LOAD", 19); #elif TRACE record_trace("LOAD"); #endif LOAD(vm, c); break; } case 0x14: /* LOAD8 */ { #ifdef DEBUG strncpy(Name, "LOAD8", 19); #elif TRACE record_trace("LOAD8"); #endif LOAD8(vm, c); break; } case 0x15: /* LOADU8 */ { #ifdef DEBUG strncpy(Name, "LOADU8", 19); #elif TRACE record_trace("LOADU8"); #endif LOADU8(vm, c); break; } case 0x16: /* LOAD16 */ { #ifdef DEBUG strncpy(Name, "LOAD16", 19); #elif TRACE record_trace("LOAD16"); #endif LOAD16(vm, c); break; } case 0x17: /* LOADU16 */ { #ifdef DEBUG strncpy(Name, "LOADU16", 19); #elif TRACE record_trace("LOADU16"); #endif LOADU16(vm, c); break; } case 0x18: /* LOAD32 */ { #ifdef DEBUG strncpy(Name, "LOAD32", 19); #elif TRACE record_trace("LOAD32"); #endif LOAD32(vm, c); break; } case 0x19: /* LOADU32 */ { #ifdef DEBUG strncpy(Name, "LOADU32", 19); #elif TRACE record_trace("LOADU32"); #endif LOADU32(vm, c); break; } case 0x1F: /* CMPUI */ { #ifdef DEBUG strncpy(Name, "CMPUI", 19); #elif TRACE record_trace("CMPUI"); #endif CMPUI(vm, c); break; } case 0x20: /* STORE */ { #ifdef DEBUG strncpy(Name, "STORE", 19); #elif TRACE record_trace("STORE"); #endif STORE(vm, c); break; } case 0x21: /* STORE8 */ { #ifdef DEBUG strncpy(Name, "STORE8", 19); #elif TRACE record_trace("STORE8"); #endif STORE8(vm, c); break; } case 0x22: /* STORE16 */ { #ifdef DEBUG strncpy(Name, "STORE16", 19); #elif TRACE record_trace("STORE16"); #endif STORE16(vm, c); break; } case 0x23: /* STORE32 */ { #ifdef DEBUG strncpy(Name, "STORE32", 19); #elif TRACE record_trace("STORE32"); #endif STORE32(vm, c); break; } case 0xB0: /* ANDI */ { #ifdef DEBUG strncpy(Name, "ANDI", 19); #elif TRACE record_trace("ANDI"); #endif ANDI(vm, c); break; } case 0xB1: /* ORI */ { #ifdef DEBUG strncpy(Name, "ORI", 19); #elif TRACE record_trace("ORI"); #endif ORI(vm, c); break; } case 0xB2: /* XORI */ { #ifdef DEBUG strncpy(Name, "XORI", 19); #elif TRACE record_trace("XORI"); #endif XORI(vm, c); break; } case 0xB3: /* NANDI */ { #ifdef DEBUG strncpy(Name, "NANDI", 19); #elif TRACE record_trace("NANDI"); #endif NANDI(vm, c); break; } case 0xB4: /* NORI */ { #ifdef DEBUG strncpy(Name, "NORI", 19); #elif TRACE record_trace("NORI"); #endif NORI(vm, c); break; } case 0xB5: /* XNORI */ { #ifdef DEBUG strncpy(Name, "XNORI", 19); #elif TRACE record_trace("XNORI"); #endif XNORI(vm, c); break; } case 0xC0: /* CMPJUMPI.G */ { #ifdef DEBUG strncpy(Name, "CMPJUMPI.G", 19); #elif TRACE record_trace("CMPJUMPI.G"); #endif CMPJUMPI_G(vm, c); break; } case 0xC1: /* CMPJUMPI.GE */ { #ifdef DEBUG strncpy(Name, "CMPJUMPI.GE", 19); #elif TRACE record_trace("CMPJUMPI.GE"); #endif CMPJUMPI_GE(vm, c); break; } case 0xC2: /* CMPJUMPI.E */ { #ifdef DEBUG strncpy(Name, "CMPJUMPI.E", 19); #elif TRACE record_trace("CMPJUMPI.E"); #endif CMPJUMPI_E(vm, c); break; } case 0xC3: /* CMPJUMPI.NE */ { #ifdef DEBUG strncpy(Name, "CMPJUMPI.NE", 19); #elif TRACE record_trace("CMPJUMPI.NE"); #endif CMPJUMPI_NE(vm, c); break; } case 0xC4: /* CMPJUMPI.LE */ { #ifdef DEBUG strncpy(Name, "CMPJUMPI.LE", 19); #elif TRACE record_trace("CMPJUMPI.LE"); #endif CMPJUMPI_LE(vm, c); break; } case 0xC5: /* CMPJUMPI.L */ { #ifdef DEBUG strncpy(Name, "CMPJUMPI.L", 19); #elif TRACE record_trace("CMPJUMPI.L"); #endif CMPJUMPI_L(vm, c); break; } case 0xD0: /* CMPJUMPUI.G */ { #ifdef DEBUG strncpy(Name, "CMPJUMPUI.G", 19); #elif TRACE record_trace("CMPJUMPUI.G"); #endif CMPJUMPUI_G(vm, c); break; } case 0xD1: /* CMPJUMPUI.GE */ { #ifdef DEBUG strncpy(Name, "CMPJUMPUI.GE", 19); #elif TRACE record_trace("CMPJUMPUI.GE"); #endif CMPJUMPUI_GE(vm, c); break; } case 0xD4: /* CMPJUMPUI.LE */ { #ifdef DEBUG strncpy(Name, "CMPJUMPUI.LE", 19); #elif TRACE record_trace("CMPJUMPUI.LE"); #endif CMPJUMPUI_LE(vm, c); break; } case 0xD5: /* CMPJUMPUI.L */ { #ifdef DEBUG strncpy(Name, "CMPJUMPUI.L", 19); #elif TRACE record_trace("CMPJUMPUI.L"); #endif CMPJUMPUI_L(vm, c); break; } default: { illegal_instruction(vm, c); break; } } #ifdef DEBUG fprintf(stdout, "# %s reg%u reg%u %i\n", Name, c->reg0, c->reg1, c->raw_Immediate); #endif return false; }
static void ff_imdct_half_altivec(FFTContext *s, FFTSample *output, const FFTSample *input) { int j, k; int n = 1 << s->mdct_bits; int n4 = n >> 2; int n8 = n >> 3; int n32 = n >> 5; const uint16_t *revtabj = s->revtab; const uint16_t *revtabk = s->revtab+n4; const vec_f *tcos = (const vec_f*)(s->tcos+n8); const vec_f *tsin = (const vec_f*)(s->tsin+n8); const vec_f *pin = (const vec_f*)(input+n4); vec_f *pout = (vec_f*)(output+n4); /* pre rotation */ k = n32-1; do { vec_f cos,sin,cos0,sin0,cos1,sin1,re,im,r0,i0,r1,i1,a,b,c,d; #define CMULA(p,o0,o1,o2,o3)\ a = pin[ k*2+p]; /* { z[k].re, z[k].im, z[k+1].re, z[k+1].im } */\ b = pin[-k*2-p-1]; /* { z[-k-2].re, z[-k-2].im, z[-k-1].re, z[-k-1].im } */\ re = vec_perm(a, b, vcprm(0,2,s0,s2)); /* { z[k].re, z[k+1].re, z[-k-2].re, z[-k-1].re } */\ im = vec_perm(a, b, vcprm(s3,s1,3,1)); /* { z[-k-1].im, z[-k-2].im, z[k+1].im, z[k].im } */\ cos = vec_perm(cos0, cos1, vcprm(o0,o1,s##o2,s##o3)); /* { cos[k], cos[k+1], cos[-k-2], cos[-k-1] } */\ sin = vec_perm(sin0, sin1, vcprm(o0,o1,s##o2,s##o3));\ r##p = im*cos - re*sin;\ i##p = re*cos + im*sin; #define STORE2(v,dst)\ j = dst;\ vec_ste(v, 0, output+j*2);\ vec_ste(v, 4, output+j*2); #define STORE8(p)\ a = vec_perm(r##p, i##p, vcprm(0,s0,0,s0));\ b = vec_perm(r##p, i##p, vcprm(1,s1,1,s1));\ c = vec_perm(r##p, i##p, vcprm(2,s2,2,s2));\ d = vec_perm(r##p, i##p, vcprm(3,s3,3,s3));\ STORE2(a, revtabk[ p*2-4]);\ STORE2(b, revtabk[ p*2-3]);\ STORE2(c, revtabj[-p*2+2]);\ STORE2(d, revtabj[-p*2+3]); cos0 = tcos[k]; sin0 = tsin[k]; cos1 = tcos[-k-1]; sin1 = tsin[-k-1]; CMULA(0, 0,1,2,3); CMULA(1, 2,3,0,1); STORE8(0); STORE8(1); revtabj += 4; revtabk -= 4; k--; } while(k >= 0); ff_fft_calc_altivec(s, (FFTComplex*)output); /* post rotation + reordering */ j = -n32; k = n32-1; do { vec_f cos,sin,re,im,a,b,c,d; #define CMULB(d0,d1,o)\ re = pout[o*2];\ im = pout[o*2+1];\ cos = tcos[o];\ sin = tsin[o];\ d0 = im*sin - re*cos;\ d1 = re*sin + im*cos; CMULB(a,b,j); CMULB(c,d,k); pout[2*j] = vec_perm(a, d, vcprm(0,s3,1,s2)); pout[2*j+1] = vec_perm(a, d, vcprm(2,s1,3,s0)); pout[2*k] = vec_perm(c, b, vcprm(0,s3,1,s2)); pout[2*k+1] = vec_perm(c, b, vcprm(2,s1,3,s0)); j++; k--; } while(k >= 0); }
static SANE_Status set_window (Abaton_Scanner * s) { uint8_t cmd[10 + 40]; uint8_t *window = cmd + 10 + 8; int invert; memset (cmd, 0, sizeof (cmd)); cmd[0] = SET_WINDOW; cmd[8] = 40; /* Just like the Apple scanners, we put the resolution here */ STORE16 (window + 2, s->val[OPT_X_RESOLUTION].w); STORE16 (window + 4, s->val[OPT_Y_RESOLUTION].w); /* Unlike Apple scanners, these are pixel values */ STORE16 (window + 6, s->ULx); STORE16 (window + 8, s->ULy); STORE16 (window + 10, s->Width); STORE16 (window + 12, s->Height); STORE8 (window + 14, s->val[OPT_BRIGHTNESS].w); STORE8 (window + 15, s->val[OPT_THRESHOLD].w); STORE8 (window + 16, s->val[OPT_CONTRAST].w); invert = s->val[OPT_NEGATIVE].w; if (!strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_LINEART)) { STORE8 (window + 17, 0); } else if (!strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_HALFTONE)) { STORE8 (window + 17, 1); } else if (!strcmp (s->val[OPT_MODE].s, "Gray256") || !strcmp (s->val[OPT_MODE].s, "Gray16")) { STORE8 (window + 17, 2); invert = !s->val[OPT_NEGATIVE].w; } else { DBG (ERROR_MESSAGE, "Can't match mode %s\n", s->val[OPT_MODE].s); return SANE_STATUS_INVAL; } STORE8 (window + 18, s->bpp); if (!strcmp (s->val[OPT_HALFTONE_PATTERN].s, "spiral")) { STORE8 (window + 20, 0); } else if (!strcmp (s->val[OPT_HALFTONE_PATTERN].s, "bayer")) { STORE8 (window + 20, 1); } else { DBG (ERROR_MESSAGE, "Can't match haftone pattern %s\n", s->val[OPT_HALFTONE_PATTERN].s); return SANE_STATUS_INVAL; } /* We have to invert these ones for some reason, so why not let the scanner do it for us... */ STORE8 (window + 21, invert ? 0x80 : 0); STORE16 (window + 22, (s->val[OPT_MIRROR].w != 0)); return sanei_scsi_cmd (s->fd, cmd, sizeof (cmd), 0, 0); }
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; }