366 {
367 if (level <= 1)
368 {
369 return (Bitmap) bmp.Clone();
370 }
371
372 int scale = 1 << (level - 1);
373 int w = bmp.Width / scale, h = bmp.Height / scale;
374
375 Bitmap dst = new Bitmap(w, h, bmp.PixelFormat);
376
377
378 if (bmp.IsIndexed())
379 {
380 BitmapData srcData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly,
381 bmp.PixelFormat);
382 BitmapData dstData = dst.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, bmp.PixelFormat);
383
384 float xStep = (float) bmp.Width / w;
385 float yStep = (float) bmp.Height / h;
386 int x, y;
387 float fx, fy;
388
389 byte* sPtr, dPtr = (byte*) dstData.Scan0;
390 if (bmp.PixelFormat == PixelFormat.Format8bppIndexed)
391 {
392 for (y = 0, fy = 0.5f; y < h; y++, fy += yStep, dPtr += dstData.Stride)
393 {
394 sPtr = (byte*) srcData.Scan0 + (int) fy * srcData.Stride;
395 for (x = 0, fx = 0.5f; x < w; x++, fx += xStep)
396 {
397 dPtr[x] = sPtr[(int) fx];
398 }
399 }
400 }
401 else
402 {
403 for (y = 0, fy = 0.5f; y < h; y++, fy += yStep, dPtr += dstData.Stride)
404 {
405 sPtr = (byte*) srcData.Scan0 + (int) fy * srcData.Stride;
406 int b = 0, ind;
407 for (x = 0, fx = 0.5f; x < w; x++, fx += xStep)
408 {
409 ind = (int) fx;
410 if ((x & 1) == 0)
411 {
412 if ((ind & 1) == 0)
413 {
414 b = sPtr[ind >> 1] & 0xF0;
415 }
416 else
417 {
418 b = sPtr[ind >> 1] << 4;
419 }
420 }
421 else
422 {
423 if ((ind & 1) == 0)
424 {
425 b |= sPtr[ind >> 1] >> 4;
426 }
427 else
428 {
429 b |= sPtr[ind >> 1] & 0xF;
430 }
431
432 dPtr[x >> 1] = (byte) b;
433 }
434 }
435
436 if ((x & 1) != 0)
437 {
438 dPtr[x >> 1] = (byte) b;
439 }
440 }
441 }
442
443 bmp.UnlockBits(srcData);
444 dst.UnlockBits(dstData);
445 }
446 else
447 {
448 using (Graphics g = Graphics.FromImage(dst))
449 {
450 g.CompositingMode = CompositingMode.SourceCopy;
451 g.CompositingQuality = CompositingQuality.HighQuality;
452 g.InterpolationMode = InterpolationMode.HighQualityBicubic;
453 g.PixelOffsetMode = PixelOffsetMode.HighQuality;
454 g.SmoothingMode = SmoothingMode.AntiAlias;
455
456 g.DrawImage(bmp, new Rectangle(0, 0, w, h));
457 }
458 }
459
460 return dst;
461 }