[Prev][Next][Index][Thread]

4bpp bidirectional mode



Has anyone gotten farther on 4bpp bidirectional mode decoding? I
haven't, still stuck with this weird every-third-scanline thing.
Is there some way to check what signals are supposed to be sent to the
camera to do the scan? My code just uses the same things that the 6bpp
bi mode does - it could well be wrong.

Here's the current version of my 4bpp bi decoder. It's written for
xfqcam, but is easy to adapt to the other qcam drivers out there.
(you'll need the xfqcam sources to pick up some of the constants.
Here's the array used to decode 4bpp to 6bpp)
  int bpp4tobpp6[16]={0,63,59,55,51,47,43,39,35,32,28,24,20,14,9,5};


/*
 * Attempt to decode a 4bpp image in bidirectional mode, based on guesses
 * from the 6bpp bi decoder. Doesn't work yet!
 * If the word read is represented in 16 bits, then the encoding looks to be:
 *
 * 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
 *  3  3  3  3  2  x  x  x  2  2  2  1  1  1  1  R
 *
 * 3, 2, and 1 represent three pixels: 1 is leftmost, 2 is middle, 3 is right.
 * The bits then seem to need to be fed through the same weird 4bpp to
 * 6bpp conversion that's used in the unidirectional mode.
 */
void
Get4bppImageBi(char *buffer) {
  int i;
  unsigned word1;

  sendcmd(QC_XFERMODE,xfermode);
  waitfor_qc_bi(quickcam_port);

  fprintf(stderr, "Taking 4bpp bi snapshot\n");

  /* Not sure why 2 is right here. The inside of this loop reads six pixels,
   * and those pixels look (sort of) valid, so you'd expect this to be += 6.
   * But that causes the camera to hang later. OTOH, only one out of every
   * three rows being read here are valid, and 6/3 = 2, so maybe that's why
   * this works. What's the right way to read here, so you don't get invalid
   * rows?
   */
  for(i=0; i< xsize*ysize; i+=2) {

    /* strobe the camera, wait until it tells us it's ready */
    outb(0x26, quickcam_port+2);
    do {
      word1 = inw(quickcam_port);
    } while( (word1 & 0x1) != 0x01);

    /* unpack the bits, convert them to grey values */
    *buffer++ = bpp4tobpp6[(word1 >> 12) & 0x0f];
    *buffer++ = bpp4tobpp6[((word1 >> 8) & 0x08) | ((word1 >> 5) & 0x07)];
    *buffer++ = bpp4tobpp6[(word1 >> 1) & 0x0f];

    /* strobe the camera again, wait */
    outb(0x2f, quickcam_port+2);
    do {
      word1 = inw(quickcam_port);
    } while ((word1 & 0x01) != 0x0);

    /* unpack the bits, convert them to grey values */
    *buffer++ = bpp4tobpp6[(word1 >> 12) & 0x0f];
    *buffer++ = bpp4tobpp6[((word1 >> 8) & 0x08) | ((word1 >> 5) & 0x07)];
    *buffer++ = bpp4tobpp6[(word1 >> 1) & 0x0f];
  }

  /* got all the pixels, strobe/wait again (why?) */
  outb(0x26, quickcam_port+2);
  do {
    word1 = inw(quickcam_port);
  } while( (word1 & 0x1) != 0x01);
  outb(0x0f, quickcam_port+2);
  return;
}