FastLED 3.9.15
Loading...
Searching...
No Matches
TJpg_Decoder Directory Reference
+ Directory dependency graph for TJpg_Decoder:

Directories

 src
 

Files

 _build.cpp.hpp
 
 driver.cpp.hpp
 
 driver.h
 

Detailed Description

Pulled from: https://github.com/Bodmer/TJpg_Decoder/commit/71bfc2607b6963ee3334ff6f601345c5d2b7a8da

Current Status

FastLED Third-Party Namespace Architecture

FastLED mandates that all third-party libraries be wrapped in the fl::third_party namespace to:

1. Prevent Global Namespace Pollution

// Before: Global namespace collision risk
class TJpg_Decoder { /* ... */ };
// After: Safely namespaced
namespace fl {
namespace third_party {
class TJpg_Decoder { /* ... */ };
}
}
Base definition for an LED controller.
Definition crgb.hpp:179

2. Clear Ownership and Licensing Boundaries

The fl::third_party namespace makes it immediately clear:

3. Controlled Integration Points

// Third-party code stays isolated
namespace fl::third_party {
class TJpg_Decoder { /* Original Arduino-style API */ };
}
// FastLED provides clean wrappers
namespace fl {
class Jpeg { // Clean C++ API following FastLED conventions
static bool decode(const JpegDecoderConfig& config, /* ... */);
private:
fl::third_party::TJpg_Decoder decoder_; // Wrapped implementation
};
}
static bool decode(const JpegConfig &config, fl::span< const fl::u8 > data, Frame *frame, fl::string *error_message=nullptr)
Definition jpeg.cpp.hpp:296

4. Implementation Benefits

Namespace Isolation

API Transformation

Maintenance Advantages

5. TJpg_Decoder Example

The TJpg_Decoder implementation demonstrates this pattern perfectly:

// File: TJpg_Decoder.h
namespace fl {
namespace third_party {
// Original TJpg_Decoder API preserved
class TJpg_Decoder {
JRESULT drawJpg(int32_t x, int32_t y, const uint8_t array[], size_t array_size);
// ... Arduino-style callback-based API
};
}
}
// File: fl/codec/jpeg.h
namespace fl {
// Clean FastLED API
class Jpeg {
static bool decode(const JpegDecoderConfig& config,
fl::span<const fl::u8> data,
Frame* frame,
fl::string* error_message = nullptr);
};
}
// File: fl/codec/jpeg.cpp
namespace fl {
class TJpgDecoder : public IDecoder {
fl::third_party::TJpg_Decoder decoder_; // Wrapped third-party code
// Bridge implementation that converts between APIs
};
}
int y
Definition simple.h:93
int x
Definition simple.h:92
JRESULT drawJpg(int32_t x, int32_t y, const uint8_t array[], size_t array_size) FL_NOEXCEPT
fl::i32 int32_t
Definition coder.h:220
unsigned char uint8_t
Definition coder.h:209

6. Guidelines for Third-Party Integration

When adding new third-party libraries to FastLED:

  1. Always use fl::third_party namespace - Non-negotiable requirement
  2. Preserve original APIs - Don't modify third-party code unnecessarily
  3. Create FastLED wrappers - Provide clean C++ APIs following project conventions
  4. Document boundaries clearly - Make it obvious what's third-party vs. FastLED native
  5. Handle type conversions - Bridge between third-party types and FastLED types
  6. Manage memory correctly - Use FastLED memory management patterns in wrappers

This architecture ensures FastLED remains maintainable, extensible, and free from the complexities often introduced by direct third-party library integration.

Implementation Summary

✅ Phase 1: Library Modernization (COMPLETED)

  1. C++ Conversion
    • tjpgd.ctjpgd.cpp
    • ✅ Updated includes and linkage
  2. Namespace Wrapping
    namespace fl {
    namespace third_party {
    // All TJpg_Decoder code wrapped here
    }
    }
    • ✅ All TJpg_Decoder classes properly namespaced
  3. Dependency Cleanup
    • ✅ Arduino-specific includes cleaned up
    • ✅ Integration with FastLED type system
    • ✅ ByteStream compatibility implemented

✅ Phase 2: FastLED Integration (COMPLETED)

  1. Bridge Implementation (src/fl/codec/jpeg.cpp)
    class TJpgDecoder : public IDecoder {
    // Complete bridge between FastLED codec API and TJpg_Decoder
    };
    • ✅ Full IDecoder interface implementation
  2. Configuration Mapping
    • JpegDecoderConfig::Quality → TJpg scaling factor
    • JpegDecoderConfig::format → pixel format conversion
    • JpegDecoderConfig::maxWidth/Height → size validation
  3. Memory Management
    • ✅ Arduino memory allocation replaced with FastLED patterns
    • fl::scoped_array and buffer management implemented
    • ✅ Callback-based output converted to frame buffer approach

✅ Phase 3: Integration & Testing (COMPLETED)

  1. Static API Implementation
    • Jpeg::decode() static methods implemented
    • Jpeg::isSupported() platform detection
    • ✅ Clean public API in fl/codec/jpeg.h
  2. Error Handling
    • JRESULT codes mapped to FastLED error system
    • ✅ Comprehensive error message reporting
  3. Advanced Features
    • ✅ Multiple pixel format support (RGB888, RGB565, RGBA8888)
    • ✅ Quality/scaling configuration
    • ✅ Memory-efficient streaming decode

Key Challenges (RESOLVED)

Current Working API

The JPEG decoder is now fully functional and integrated into FastLED. Here's how to use it:

Basic Usage

#include "fl/codec/jpeg.h"
// Simple decode to new Frame
fl::JpegDecoderConfig config;
config.format = fl::PixelFormat::RGB888;
config.quality = fl::JpegDecoderConfig::Medium;
fl::string error;
auto frame = fl::Jpeg::decode(config, jpeg_data_span, &error);
if (!frame) {
printf("JPEG decode failed: %s\n", error.c_str());
}
const char * c_str() const FL_NOEXCEPT

Advanced Configuration

// Custom configuration
fl::JpegDecoderConfig config;
config.quality = fl::JpegDecoderConfig::High; // High quality (1:1 scaling)
config.format = fl::PixelFormat::RGBA8888; // With alpha channel
config.maxWidth = 1920; // Size limits
config.maxHeight = 1080;
// Decode to existing Frame
fl::Frame myFrame(width, height);
bool success = fl::Jpeg::decode(config, jpeg_data, &myFrame, &error);

Platform Support

// Check if JPEG decoding is available
// JPEG decoding available
} else {
// Platform doesn't support JPEG
}
static bool isSupported()
Definition jpeg.cpp.hpp:376

Integration with FastLED Codecs

The JPEG decoder integrates seamlessly with FastLED's codec architecture:

Unit Test Design

Existing test framework: tests/codec_jpeg.cpp

Current Test Coverage

Additional Tests Required for TJpg Integration

Phase 1: Basic Functionality

TEST_CASE("JPEG TJpg decoder initialization") {
// Test TJpgDecoder specific initialization
// Verify workspace allocation
// Check namespace wrapping
}
TEST_CASE("JPEG valid file decoding") {
// Test with minimal valid JPEG data
// Verify frame dimensions and pixel data
// Check memory allocation patterns
}

Phase 2: Format Support

TEST_CASE("JPEG pixel format conversion") {
// Test RGB888, RGB565, RGBA8888 output formats
// Verify color space conversion accuracy
// Check byte ordering and alignment
}
TEST_CASE("JPEG scaling and quality") {
// Test JpegConfig::Quality mapping to TJpg scale factors
// Verify image scaling (1/1, 1/2, 1/4, 1/8)
// Performance benchmarks for different settings
}

Phase 3: Edge Cases & Performance

TEST_CASE("JPEG large image handling") {
// Test maxWidth/maxHeight enforcement
// Memory usage validation
// Progressive JPEG support
}
TEST_CASE("JPEG malformed data") {
// Truncated files, invalid headers
// Error recovery and cleanup
// Memory leak detection
}
TEST_CASE("JPEG stress testing") {
// Multiple decode operations
// Concurrent decoder instances
// Memory fragmentation scenarios
}

Test Data Requirements

Integration with Existing Test Suite

Status: Test suite updated and functional

  1. CHECK_FALSE(jpegSupported) replaced with CHECK(jpegSupported)
  2. ✅ TJpg-specific test cases added alongside generic codec tests
  3. ✅ Tests pass with TJpg_Decoder implementation

API Integration (COMPLETED)

Main FastLED API entry point: src/fl/codec/jpeg.h

Summary

The TJpg_Decoder integration is COMPLETE and fully functional. The JPEG decoder now provides:

  1. Clean C++ API following FastLED conventions
  2. Multiple pixel formats (RGB888, RGB565, RGBA8888)
  3. Quality/scaling control via configuration
  4. Memory-efficient operation using FastLED buffer management
  5. Comprehensive error handling with descriptive messages
  6. Full test coverage and validation

The decoder is ready for production use in FastLED applications requiring JPEG image decoding capabilities.