Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(23)

Side by Side Diff: src/codec/SkBmpCodec.cpp

Issue 1287423002: Scanline decoding for bmp (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Response to comments - Does not compile - Needs rebase for conv_poss update Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkBmpCodec.h" 8 #include "SkBmpCodec.h"
9 #include "SkBmpMaskCodec.h" 9 #include "SkBmpMaskCodec.h"
10 #include "SkBmpRLECodec.h" 10 #include "SkBmpRLECodec.h"
(...skipping 26 matching lines...) Expand all
37 kBitMasks_BmpCompressionMethod = 3, 37 kBitMasks_BmpCompressionMethod = 3,
38 kJpeg_BmpCompressionMethod = 4, 38 kJpeg_BmpCompressionMethod = 4,
39 kPng_BmpCompressionMethod = 5, 39 kPng_BmpCompressionMethod = 5,
40 kAlphaBitMasks_BmpCompressionMethod = 6, 40 kAlphaBitMasks_BmpCompressionMethod = 6,
41 kCMYK_BmpCompressionMethod = 11, 41 kCMYK_BmpCompressionMethod = 11,
42 kCMYK8BitRLE_BmpCompressionMethod = 12, 42 kCMYK8BitRLE_BmpCompressionMethod = 12,
43 kCMYK4BitRLE_BmpCompressionMethod = 13 43 kCMYK4BitRLE_BmpCompressionMethod = 13
44 }; 44 };
45 45
46 /* 46 /*
47 * Used to define the input format of the bmp
48 */
49 enum BmpInputFormat {
50 kStandard_BmpInputFormat,
51 kRLE_BmpInputFormat,
52 kBitMask_BmpInputFormat,
53 kUnknown_BmpInputFormat
54 };
55
56 /*
57 * Checks the start of the stream to see if the image is a bitmap 47 * Checks the start of the stream to see if the image is a bitmap
58 */ 48 */
59 bool SkBmpCodec::IsBmp(SkStream* stream) { 49 bool SkBmpCodec::IsBmp(SkStream* stream) {
60 // TODO: Support "IC", "PT", "CI", "CP", "BA" 50 // TODO: Support "IC", "PT", "CI", "CP", "BA"
61 const char bmpSig[] = { 'B', 'M' }; 51 const char bmpSig[] = { 'B', 'M' };
62 char buffer[sizeof(bmpSig)]; 52 char buffer[sizeof(bmpSig)];
63 return stream->read(buffer, sizeof(bmpSig)) == sizeof(bmpSig) && 53 return stream->read(buffer, sizeof(bmpSig)) == sizeof(bmpSig) &&
64 !memcmp(buffer, bmpSig, sizeof(bmpSig)); 54 !memcmp(buffer, bmpSig, sizeof(bmpSig));
65 } 55 }
66 56
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 455
466 if (codecOut) { 456 if (codecOut) {
467 // Set the image info 457 // Set the image info
468 const SkImageInfo& imageInfo = SkImageInfo::Make(width, height, 458 const SkImageInfo& imageInfo = SkImageInfo::Make(width, height,
469 colorType, alphaType); 459 colorType, alphaType);
470 460
471 // Return the codec 461 // Return the codec
472 switch (inputFormat) { 462 switch (inputFormat) {
473 case kStandard_BmpInputFormat: 463 case kStandard_BmpInputFormat:
474 *codecOut = SkNEW_ARGS(SkBmpStandardCodec, (imageInfo, stream, 464 *codecOut = SkNEW_ARGS(SkBmpStandardCodec, (imageInfo, stream,
475 bitsPerPixel, numColors, bytesPerColor, 465 inputFormat, bitsPerPixel, numColors, bytesPerColor,
476 offset - bytesRead, rowOrder, inIco)); 466 offset - bytesRead, rowOrder, inIco));
477 return true; 467 return true;
478 case kBitMask_BmpInputFormat: 468 case kBitMask_BmpInputFormat:
479 // Bmp-in-Ico must be standard mode 469 // Bmp-in-Ico must be standard mode
480 if (inIco) { 470 if (inIco) {
481 SkCodecPrintf("Error: Icos may not use bit mask format.\n"); 471 SkCodecPrintf("Error: Icos may not use bit mask format.\n");
482 return false; 472 return false;
483 } 473 }
484 // Skip to the start of the pixel array. 474 // Skip to the start of the pixel array.
485 // We can do this here because there is no color table to read 475 // We can do this here because there is no color table to read
486 // in bit mask mode. 476 // in bit mask mode.
487 if (stream->skip(offset - bytesRead) != offset - bytesRead) { 477 if (stream->skip(offset - bytesRead) != offset - bytesRead) {
488 SkCodecPrintf("Error: unable to skip to image data.\n"); 478 SkCodecPrintf("Error: unable to skip to image data.\n");
489 return false; 479 return false;
490 } 480 }
491 481
492 *codecOut = SkNEW_ARGS(SkBmpMaskCodec, (imageInfo, stream, 482 *codecOut = SkNEW_ARGS(SkBmpMaskCodec, (imageInfo, stream,
493 bitsPerPixel, masks.detach(), rowOrder)); 483 inputFormat, bitsPerPixel, masks.detach(), rowOrder));
494 return true; 484 return true;
495 case kRLE_BmpInputFormat: 485 case kRLE_BmpInputFormat:
496 // Bmp-in-Ico must be standard mode 486 // Bmp-in-Ico must be standard mode
497 // When inIco is true, this line cannot be reached, since we 487 // When inIco is true, this line cannot be reached, since we
498 // require that RLE Bmps have a valid number of totalBytes, and 488 // require that RLE Bmps have a valid number of totalBytes, and
499 // Icos skip the header that contains totalBytes. 489 // Icos skip the header that contains totalBytes.
500 SkASSERT(!inIco); 490 SkASSERT(!inIco);
501 *codecOut = SkNEW_ARGS(SkBmpRLECodec, ( 491 *codecOut = SkNEW_ARGS(SkBmpRLECodec, (
502 imageInfo, stream, bitsPerPixel, numColors, 492 imageInfo, stream, inputFormat, bitsPerPixel, numColors,
503 bytesPerColor, offset - bytesRead, rowOrder, RLEBytes)); 493 bytesPerColor, offset - bytesRead, rowOrder, RLEBytes));
504 return true; 494 return true;
505 default: 495 default:
506 SkASSERT(false); 496 SkASSERT(false);
507 return false; 497 return false;
508 } 498 }
509 } 499 }
510 500
511 return true; 501 return true;
512 } 502 }
513 503
514 /* 504 /*
515 * Creates a bmp decoder 505 * Creates a bmp decoder
516 * Reads enough of the stream to determine the image format 506 * Reads enough of the stream to determine the image format
517 */ 507 */
518 SkCodec* SkBmpCodec::NewFromStream(SkStream* stream, bool inIco) { 508 SkCodec* SkBmpCodec::NewFromStream(SkStream* stream, bool inIco) {
519 SkAutoTDelete<SkStream> streamDeleter(stream); 509 SkAutoTDelete<SkStream> streamDeleter(stream);
520 SkCodec* codec = NULL; 510 SkCodec* codec = NULL;
521 if (ReadHeader(stream, inIco, &codec)) { 511 if (ReadHeader(stream, inIco, &codec)) {
522 // codec has taken ownership of stream, so we do not need to 512 // codec has taken ownership of stream, so we do not need to
523 // delete it. 513 // delete it.
524 SkASSERT(codec); 514 SkASSERT(codec);
525 streamDeleter.detach(); 515 streamDeleter.detach();
526 return codec; 516 return codec;
527 } 517 }
528 return NULL; 518 return NULL;
529 } 519 }
530 520
531 SkBmpCodec::SkBmpCodec(const SkImageInfo& info, SkStream* stream, 521 SkBmpCodec::SkBmpCodec(const SkImageInfo& info, SkStream* stream,
532 uint16_t bitsPerPixel, RowOrder rowOrder) 522 BmpInputFormat inputFormat, uint16_t bitsPerPixel, RowOrder rowOrder)
533 : INHERITED(info, stream) 523 : INHERITED(info, stream)
524 , fInputFormat(inputFormat)
534 , fBitsPerPixel(bitsPerPixel) 525 , fBitsPerPixel(bitsPerPixel)
535 , fRowOrder(rowOrder) 526 , fRowOrder(rowOrder)
536 {} 527 {}
537 528
538 bool SkBmpCodec::onRewind() { 529 bool SkBmpCodec::onRewind() {
539 return SkBmpCodec::ReadHeader(this->stream(), this->inIco(), NULL); 530 return SkBmpCodec::ReadHeader(this->stream(), this->inIco(), NULL);
540 } 531 }
541 532
542 /* 533 /*
543 * Get the destination row to start filling from 534 * Get the destination row to start filling from
(...skipping 11 matching lines...) Expand all
555 */ 546 */
556 uint32_t SkBmpCodec::computeNumColors(uint32_t numColors) { 547 uint32_t SkBmpCodec::computeNumColors(uint32_t numColors) {
557 // Zero is a default for maxColors 548 // Zero is a default for maxColors
558 // Also set numColors to maxColors when it is too large 549 // Also set numColors to maxColors when it is too large
559 uint32_t maxColors = 1 << fBitsPerPixel; 550 uint32_t maxColors = 1 << fBitsPerPixel;
560 if (numColors == 0 || numColors >= maxColors) { 551 if (numColors == 0 || numColors >= maxColors) {
561 return maxColors; 552 return maxColors;
562 } 553 }
563 return numColors; 554 return numColors;
564 } 555 }
556
557 /*
558 * Scanline decoder for bmps
559 */
560 class SkBmpScanlineDecoder : public SkScanlineDecoder {
561 public:
562 SkBmpScanlineDecoder(SkBmpCodec* codec)
563 : INHERITED(codec->getInfo())
564 , fCodec(codec)
565 {}
566
567 SkCodec::Result onStart(const SkImageInfo& dstInfo, const SkCodec::Options& options,
568 SkPMColor inputColorPtr[], int* inputColorCount) ove rride {
569 if (!fCodec->rewindIfNeeded()) {
570 return SkCodec::kCouldNotRewind;
571 }
572 if (options.fSubset) {
573 // Subsets are not supported.
574 return SkCodec::kUnimplemented;
575 }
576 if (dstInfo.dimensions() != fCodec->getInfo().dimensions()) {
577 SkCodecPrintf("Error: scaling not supported.\n");
578 return SkCodec::kInvalidScale;
579 }
580 if (!conversion_possible(dstInfo, fCodec->getInfo())) {
581 SkCodecPrintf("Error: cannot convert input type to output type.\n");
582 return SkCodec::kInvalidConversion;
583 }
584
585 return fCodec->onStart(dstInfo, options, inputColorPtr, inputColorCount) ;
586 }
587
588 SkCodec::Result onGetScanlines(void* dst, int count, size_t rowBytes) {
589 // Create a new image info representing the portion of the image to deco de
590 SkImageInfo rowInfo = this->dstInfo().makeWH(this->dstInfo().width(), co unt);
591
592 // Decode the requested rows
593 return fCodec->decode(rowInfo, dst, rowBytes, this->options());
594 }
595
596 // TODO(msarett): Override default skipping with something more clever.
597 // TODO(msarett): Consider other optimizations for this codec.
scroggo 2015/08/14 21:53:00 Do you have any optimizations in mind?
msarett 2015/08/17 19:16:13 Not in particular. I just don't think I've analyz
scroggo 2015/08/26 22:40:09 Great. These would be good candidates to specifica
598
599 private:
600 SkAutoTDelete<SkBmpCodec> fCodec;
601
602 typedef SkScanlineDecoder INHERITED;
603 };
604
605 SkScanlineDecoder* SkBmpCodec::NewSDFromStream(SkStream* stream) {
606 SkAutoTDelete<SkBmpCodec> codec(static_cast<SkBmpCodec*>(SkBmpCodec::NewFrom Stream(stream)));
607 if (!codec) {
608 return NULL;
609 }
610
611 return SkNEW_ARGS(SkBmpScanlineDecoder, (codec));
612 }
OLDNEW
« src/codec/SkBmpCodec.h ('K') | « src/codec/SkBmpCodec.h ('k') | src/codec/SkBmpMaskCodec.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698