Logo Search packages:      
Sourcecode: fbdesk version File versions  Download package

XImage * FbTk::TextureRender::renderXImage (  )  [private]

Render to XImage

Returns:
allocated and rendered XImage, user is responsible to deallocate

Definition at line 261 of file TextureRender.cc.

References FbTk::ImageControl::colorsPerChannel(), FbTk::ImageControl::depth(), FbTk::App::display(), FbTk::ImageControl::doDither(), FbTk::App::instance(), FbTk::ImageControl::screenNum(), and FbTk::ImageControl::visual().

Referenced by renderPixmap().

                                    {
    Display *disp = FbTk::App::instance()->display();
    XImage *image =
        XCreateImage(disp,
                     DefaultVisual(disp, control.screenNum()), control.depth(), ZPixmap, 0, 0,
                     width, height, 32, 0);

    if (! image) {
        cerr<<"FbTk::TextureRender::renderXImage(): error creating XImage"<<endl;
        return 0;
    }

    image->data = 0;

    unsigned char *d = new unsigned char[image->bytes_per_line * (height + 1)];
    register unsigned int x, y, dithx, dithy, r, g, b, o, er, eg, eb, offset;

    unsigned char *pixel_data = d, *ppixel_data = d;
    unsigned long pixel;

    o = image->bits_per_pixel + ((image->byte_order == MSBFirst) ? 1 : 0);

    if (control.doDither() && width > 1 && height > 1) {
        unsigned char dither4[4][4] = { 
            {0, 4, 1, 5},
            {6, 2, 7, 3},
            {1, 5, 0, 4},
            {7, 3, 6, 2} };

#ifdef ORDEREDPSEUDO
        unsigned char dither8[8][8] = { 
            { 0, 32,  8, 40, 2,     34, 10, 42 },
            { 48, 16, 56, 24, 50, 18, 58, 26 },
            { 12, 44,  4, 36, 14, 46, 6, 38 },
            { 60, 28, 52, 20, 62, 30, 54, 22 },
            { 3, 35, 11, 43, 1,     33, 9, 41 },
            { 51, 19, 59, 27, 49, 17, 57, 25 },
            { 15, 47,  7, 39, 13, 45, 5, 37 },
            { 63, 31, 55, 23, 61, 29, 53, 21 } };
#endif // ORDEREDPSEUDO

        switch (control.visual()->c_class) {
        case TrueColor:
            // algorithm: ordered dithering... many many thanks to rasterman
            // (raster@rasterman.com) for telling me about this... portions of this
            // code is based off of his code in Imlib
            for (y = 0, offset = 0; y < height; y++) {
                dithy = y & 0x3;

                for (x = 0; x < width; x++, offset++) {
                    dithx = x & 0x3;
                    r = red[offset];
                    g = green[offset];
                    b = blue[offset];

                    er = r & (red_bits - 1);
                    eg = g & (green_bits - 1);
                    eb = b & (blue_bits - 1);

                    r = red_table[r];
                    g = green_table[g];
                    b = blue_table[b];

                    if ((dither4[dithy][dithx] < er) && (r < red_table[255])) r++;
                    if ((dither4[dithy][dithx] < eg) && (g < green_table[255])) g++;
                    if ((dither4[dithy][dithx] < eb) && (b < blue_table[255])) b++;

                    pixel = (r << red_offset) | (g << green_offset) | (b << blue_offset);

                    switch (o) {
                    case      8: // 8bpp
                        *pixel_data++ = pixel;
                        break;

                    case 16: // 16bpp LSB
                        *pixel_data++ = pixel;
                        *pixel_data++ = pixel >> 8;
                        break;

                    case 17: // 16bpp MSB
                        *pixel_data++ = pixel >> 8;
                        *pixel_data++ = pixel;
                        break;

                    case 24: // 24bpp LSB
                        *pixel_data++ = pixel;
                        *pixel_data++ = pixel >> 8;
                        *pixel_data++ = pixel >> 16;
                        break;

                    case 25: // 24bpp MSB
                        *pixel_data++ = pixel >> 16;
                        *pixel_data++ = pixel >> 8;
                        *pixel_data++ = pixel;
                        break;

                    case 32: // 32bpp LSB
                        *pixel_data++ = pixel;
                        *pixel_data++ = pixel >> 8;
                        *pixel_data++ = pixel >> 16;
                        *pixel_data++ = pixel >> 24;
                        break;

                    case 33: // 32bpp MSB
                        *pixel_data++ = pixel >> 24;
                        *pixel_data++ = pixel >> 16;
                        *pixel_data++ = pixel >> 8;
                        *pixel_data++ = pixel;
                        break;
                    }
                }

                pixel_data = (ppixel_data += image->bytes_per_line);
            }

            break;

        case StaticColor:
        case PseudoColor: {
#ifndef      ORDEREDPSEUDO
            short *terr,
                *rerr = new short[width + 2],
                *gerr = new short[width + 2],
                *berr = new short[width + 2],
                *nrerr = new short[width + 2],
                *ngerr = new short[width + 2],
                *nberr = new short[width + 2];
            int rr, gg, bb, rer, ger, ber;
            int dd = 255 / control.colorsPerChannel();

            for (x = 0; x < width; x++) {
                *(rerr + x) = *(red + x);
                *(gerr + x) = *(green + x);
                *(berr + x) = *(blue + x);
            }

            *(rerr + x) = *(gerr + x) = *(berr + x) = 0;
#endif // ORDEREDPSEUDO

            for (y = 0, offset = 0; y < height; y++) {
#ifdef            ORDEREDPSEUDO
                dithy = y & 7;

                for (x = 0; x < width; x++, offset++) {
                    dithx = x & 7;

                    r = red[offset];
                    g = green[offset];
                    b = blue[offset];

                    er = r & (red_bits - 1);
                    eg = g & (green_bits - 1);
                    eb = b & (blue_bits - 1);

                    r = red_table[r];
                    g = green_table[g];
                    b = blue_table[b];

                    if ((dither8[dithy][dithx] < er) && (r < red_table[255])) r++;
                    if ((dither8[dithy][dithx] < eg) && (g < green_table[255])) g++;
                    if ((dither8[dithy][dithx] < eb) && (b < blue_table[255])) b++;

                    pixel = (r * cpccpc) + (g * cpc) + b;
                    *(pixel_data++) = colors[pixel].pixel;
                }

                pixel_data = (ppixel_data += image->bytes_per_line);
            }
#else // !ORDEREDPSEUDO
            if (y < (height - 1)) {
                int i = offset + width;
                for (x = 0; x < width; x++, i++) {
                    *(nrerr + x) = *(red + i);
                    *(ngerr + x) = *(green + i);
                    *(nberr + x) = *(blue + i);
                }

                *(nrerr + x) = *(red + (--i));
                *(ngerr + x) = *(green + i);
                *(nberr + x) = *(blue + i);
            }

            for (x = 0; x < width; x++) {
                rr = rerr[x];
                gg = gerr[x];
                bb = berr[x];

                if (rr > 255) rr = 255; else if (rr < 0) rr = 0;
                if (gg > 255) gg = 255; else if (gg < 0) gg = 0;
                if (bb > 255) bb = 255; else if (bb < 0) bb = 0;

                r = red_table[rr];
                g = green_table[gg];
                b = blue_table[bb];

                rer = rerr[x] - r*dd;
                ger = gerr[x] - g*dd;
                ber = berr[x] - b*dd;

                pixel = (r * cpccpc) + (g * cpc) + b;
                *pixel_data++ = colors[pixel].pixel;

                r = rer >> 1;
                g = ger >> 1;
                b = ber >> 1;
                rerr[x+1] += r;
                gerr[x+1] += g;
                berr[x+1] += b;
                nrerr[x] += r;
                ngerr[x] += g;
                nberr[x] += b;
            }

            offset += width;

            pixel_data = (ppixel_data += image->bytes_per_line);

            terr = rerr;
            rerr = nrerr;
            nrerr = terr;

            terr = gerr;
            gerr = ngerr;
            ngerr = terr;

            terr = berr;
            berr = nberr;
            nberr = terr;
        }

        delete [] rerr;
        delete [] gerr;
        delete [] berr;
        delete [] nrerr;
        delete [] ngerr;
        delete [] nberr;
#endif // ORDEREDPSUEDO

        } break;

        /*
          case StaticGray:
          case GrayScale:
          for (y = 0, offset = 0; y < height; y++) {
          dithy = y & 0x3;

          for (x = 0; x < width; x++, offset++) {
          dithx = x & 0x3;

          r = *(red + offset);
          g = *(green + offset);
          b = *(blue + offset);

          er = r & 0x7;
          eg = g & 0x7;
          eb = b & 0x7;

          if ((dither[dithy][dithx] < er) && (r < (256 - 8)))
          r += 8;
          if ((dither[dithy][dithx] < (eg << 1)) && (g < (256 - 4)))
          g += 4;
          if ((dither[dithy][dithx] < eb) && (b < (256 - 8)))
          b += 8;

          r = *(red_table + r);
          g = *(green_table + g);
          b = *(blue_table + b);

          g = ((r * 30) + (g * 59) + (b * 11)) / 100;
          *pixel_data++ = colors[g].pixel;
          }

          pixel_data = (ppixel_data += image->bytes_per_line);
          }

          break;
        */

    default:
        cerr<<"TextureRender::renderXImage(): unsupported visual"<<endl;
        delete [] d;
        XDestroyImage(image);
        return (XImage *) 0;
    }
} else {
    switch (control.visual()->c_class) {
    case StaticColor:
    case PseudoColor:
        for (y = 0, offset = 0; y < height; y++) {
            for (x = 0; x < width; x++, offset++) {
                r = red_table[red[offset]];
                g = green_table[green[offset]];
                b = blue_table[blue[offset]];

                pixel = (r * cpccpc) + (g * cpc) + b;
                *pixel_data++ = colors[pixel].pixel;
            }

            pixel_data = (ppixel_data += image->bytes_per_line);
        }

        break;

    case TrueColor:
        for (y = 0, offset = 0; y < height; y++) {
            for (x = 0; x < width; x++, offset++) {
                r = red_table[red[offset]];
                g = green_table[green[offset]];
                b = blue_table[blue[offset]];

                pixel = (r << red_offset) | (g << green_offset) | (b << blue_offset);

                switch (o) {
                case    8: // 8bpp
                    *pixel_data++ = pixel;
                    break;

                case 16: // 16bpp LSB
                    *pixel_data++ = pixel;
                    *pixel_data++ = pixel >> 8;
                    break;

                case 17: // 16bpp MSB
                    *pixel_data++ = pixel >> 8;
                    *pixel_data++ = pixel;
                    break;

                case 24: // 24bpp LSB
                    *pixel_data++ = pixel;
                    *pixel_data++ = pixel >> 8;
                    *pixel_data++ = pixel >> 16;
                    break;

                case 25: // 24bpp MSB
                    *pixel_data++ = pixel >> 16;
                    *pixel_data++ = pixel >> 8;
                    *pixel_data++ = pixel;
                    break;

                case 32: // 32bpp LSB
                    *pixel_data++ = pixel;
                    *pixel_data++ = pixel >> 8;
                    *pixel_data++ = pixel >> 16;
                    *pixel_data++ = pixel >> 24;
                    break;

                case 33: // 32bpp MSB
                    *pixel_data++ = pixel >> 24;
                    *pixel_data++ = pixel >> 16;
                    *pixel_data++ = pixel >> 8;
                    *pixel_data++ = pixel;
                    break;
                }
            }

            pixel_data = (ppixel_data += image->bytes_per_line);
        }

        break;

    case StaticGray:
    case GrayScale:
        for (y = 0, offset = 0; y < height; y++) {
            for (x = 0; x < width; x++, offset++) {
                r = *(red_table + *(red + offset));
                g = *(green_table + *(green + offset));
                b = *(blue_table + *(blue + offset));

                g = ((r * 30) + (g * 59) + (b * 11)) / 100;
                *pixel_data++ = colors[g].pixel;
            }

            pixel_data = (ppixel_data += image->bytes_per_line);
        }

      break;

    default:
        cerr<<"TextureRender::renderXImage(): unsupported visual"<<endl;
        delete [] d;
        XDestroyImage(image);
        return (XImage *) 0;
    }
}

image->data = (char *) d;
return image;
}


Generated by  Doxygen 1.6.0   Back to index