title: c++: Convert 24bpp to 8 bpp or 1bpp image
body: <p>I have to convert a <code>24bpp</code> image to a <code>1bpp</code> image or <code>8bpp</code> image based on color table. The caller expects a <code>unsigned char*</code> in either case (which would be further processed or maybe for now debug output by sending the <code>BITMAPINFOHEADER.biBitCount</code> to its proper value, 8 or 1).</p>
  
  <p>I have code to extract the color index into the palette (colorIndexArray is from color conversion or dithering algorithms)... I can get the info for an 8bpp bitmap...</p>
  
  <p>But my problem is, I don't know how to put this info into a 1bpp bitmap </p>
  
  <pre><code>typedef struct {
      unsigned int size;
      unsigned char* pixels;
  } ColorIndexArray;
  
  unsigned char* convertImage(const ColorIndexArray&amp; colorIndexArray, unsigned int paletteSize)
  {
      unsigned char* outputImage;
      if (paleteSize &gt; 2)
      {
          outputImage = (unsigned char*)LocalAlloc(LPTR, colorIndexArray.size);
          for (int i=0; i&lt;colorIndexArray.size; i++)
              *(outputImage+i) = colorIndexArray.pixels[i];  
          // this works great              
      }
      else  // monochrome, caller has palette colors likely b/w (or purple/magenta or anything), must be 1bpp
      {
          outputImage = (unsigned char*)LocalAlloc(LPTR, colorIndexArray.size / 8);
          // how can i place the unsigned char* info (which is already 
          // determined based on desired algorithm, representing index in 
          // color table) into the output image inside a single bit ?
          // (obviously its value for a monochrome image would be 0 or 1 but    
          // it is saved as unsigned char* at the algorithm output) 
          // And how do I advance the pointer ?
          // Will it be type safe ? Aligned to byte ? or do I have to fill 
          // with something at the end to make multiple of 8 bits ?
      }
  
      return outputImage;
  }
  </code></pre>
  
  <p>Trying this after comment suggestion:</p>
  
  <pre><code>#include &lt;GdiPlus.h&gt;
  ....
  else {
      Gdiplus::Bitmap monoBitmap(w, h, PixelFormat1bppIndexed);
      Gdiplus::BitmapData monoBitmapData;
      Gdiplus::Rect rect(0, 0, w, h);
      monoBitmap.LockBits(&amp;rect, Gdiplus::ImageLockModeWrite, PixelFormat1bppIndexed, &amp;monoBitmapData);
      outputImage = (unsigned char*)monoBitmapData.Scan0;
  
      for (unsigned int y = 0; y &lt; h; y++)
      {
          for (unsigned int x = 0; x &lt; w; x++)
          {
              if (colorIndexArray.pixels[x + y * w])
                  outputImage[y*monoBitmapData.Stride + x / 8] |= (unsigned char)(0x80 &gt;&gt; (x % 8));
          }           
      }
      monoBitmap.UnlockBits(&amp;monoBitmapData); 
  }
  return outputImage;
  </code></pre>
  
  <p>(Also need to allocate the memory for outputImage)</p>