This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

 

  Image Dither
  Submitted by



This code snippet is code to convert any format of image to another format, and dithers the image while converting using a very simplified error diffusion algorithm inspired by Floyd Steinberg's.

I'm getting about 185ms times for conversion and dithering of 32bit 800x600 image to 16bit A1R5G5B5 images on my PII 450Mhz, not too great, but not too bad either, feedback is welcome on ways you might think up to optimize the code.

I've attached two images showing the quality gain in 16bits. As you can see, even though the algorithm is very simple, the quality increase of sprites and textures can be pretty big nonetheless in 16-bits video modes.

Example images:
  • http://www.flipcode.com/misc/Dithered.jpg
  • http://www.flipcode.com/misc/NotDithered.jpg

  • Orbitalx

    Download Associated File: ConvertAndDither.cpp (2,578 bytes)

    COTD submitted by Benjamin Contant [bcontant@videotron.ca] (posted 08/20/2001)

    DWORD SrcColor = 0; DWORD DestColor; BYTE SrcAlpha, SrcRed, SrcGreen, SrcBlue; BYTE DestAlpha, DestRed, DestGreen, DestBlue; BYTE RedError, GreenError, BlueError, AlphaError;

    for(int i = 0; i < Height; i++) { //Reset the error after every line because we don't want //the error of the last pixel to be used on the first pixel //of this line RedError = GreenError = BlueError = AlphaError = 0;

    for(int j = 0; j < Width; j++) { //Read in the source color SrcColor = 0; for(int k = 0; k < SrcBytesPerPixel; k++) { SrcColor += (SrcPtr[k] << (k<<3)); }

    //Extract the ARGB components if(SrcAlphaNumBits > 0) { SrcAlpha = (SrcColor & SrcAlphaMask) >> SrcAlphaShift; } else { SrcAlpha = 255; } SrcRed = (SrcColor & SrcRedMask) >> SrcRedShift; SrcGreen = (SrcColor & SrcGreenMask) >> SrcGreenShift; SrcBlue = (SrcColor & SrcBlueMask) >> SrcBlueShift;

    //Add the error while clamping to the max color value if(SrcAlphaNumBits > 0) { SrcAlpha = min(MaxSrcAlpha, SrcAlpha + AlphaError); } SrcRed = min(MaxSrcRed, SrcRed + RedError); SrcGreen = min(MaxSrcGreen, SrcGreen + GreenError); SrcBlue = min(MaxSrcBlue, SrcBlue + BlueError); //Calculate the resulting destination colors if(SrcAlphaNumBits > 0) { DestAlpha = SrcAlpha >> AlphaBitDiff; } else { DestAlpha = SrcAlpha >> (8 - DestAlphaNumBits); } DestRed = SrcRed >> RedBitDiff; DestGreen = SrcGreen >> GreenBitDiff; DestBlue = SrcBlue >> BlueBitDiff;

    //Calculate the error if(SrcAlphaNumBits > 0) { AlphaError = SrcAlpha - (DestAlpha << AlphaBitDiff); } else { AlphaError = 0; } RedError = SrcRed - (DestRed << RedBitDiff); GreenError = SrcGreen - (DestGreen << GreenBitDiff); BlueError = SrcBlue - (DestBlue << BlueBitDiff);

    //Compose the destination pixel DestColor = (DestAlpha << DestAlphaShift) + (DestRed << DestRedShift) + (DestGreen << DestGreenShift) + (DestBlue << DestBlueShift); //Set the destination pixel BYTE* DestColorPtr = (BYTE*) &DestColor; for(k = 0; k < DestBytesPerPixel; k++) { DestPtr[k] = DestColorPtr[k]; }

    //Advance the pointers to the next pixel DestPtr += DestBytesPerPixel; SrcPtr += SrcBytesPerPixel; }

    //Advance the pointers to the next line DestPtr += DestPitch - (Width * DestBytesPerPixel); SrcPtr += SrcPitch - (Width * SrcBytesPerPixel); }

    The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.

     

    Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
    Please read our Terms, Conditions, and Privacy information.