• sRGB vs REC709 – An introduction and FFmpeg implementations

    ,

    1. Basic Comparison

    • What they are
      • sRGB: A standard “web”/computer-display RGB color space defined by IEC 61966-2-1. It’s used for most monitors, cameras, printers, and the vast majority of images on the Internet.
      • Rec. 709: An HD-video color space defined by ITU-R BT.709. It’s the go-to standard for HDTV broadcasts, Blu-ray discs, and professional video pipelines.
    • Why they exist
      • sRGB: Ensures consistent colors across different consumer devices (PCs, phones, webcams).
      • Rec. 709: Ensures consistent colors across video production and playback chains (cameras → editing → broadcast → TV).
    • What you’ll see
      • On your desktop or phone, images tagged sRGB will look “right” without extra tweaking.
      • On an HDTV or video-editing timeline, footage tagged Rec. 709 will display accurate contrast and hue on broadcast-grade monitors.

    2. Digging Deeper

    FeaturesRGBRec. 709
    White pointD65 (6504 K), same for bothD65 (6504 K)
    Primaries (x,y)R: (0.640, 0.330) G: (0.300, 0.600) B: (0.150, 0.060)R: (0.640, 0.330) G: (0.300, 0.600) B: (0.150, 0.060)
    Gamut sizeIdentical triangle on CIE 1931 chartIdentical to sRGB
    Gamma / transferPiecewise curve: approximate 2.2 with linear toePure power-law γ≈2.4 (often approximated as 2.2 in practice)
    Matrix coefficientsN/A (pure RGB usage)Y = 0.2126 R + 0.7152 G + 0.0722 B (Rec. 709 matrix)
    Typical bit-depth8-bit/channel (with 16-bit variants)8-bit/channel (10-bit for professional video)
    Usage metadataTagged as “sRGB” in image files (PNG, JPEG, etc.)Tagged as “bt709” in video containers (MP4, MOV)
    Color rangeFull-range RGB (0–255)Studio-range Y′CbCr (Y′ [16–235], Cb/Cr [16–240])


    Why the Small Differences Matter

    (more…)
  • Convert between light exposure and intensity

    ,
    import math,sys
    
    def Exposure2Intensity(exposure): 
        exp = float(exposure)
        result = math.pow(2,exp)
        print(result)
    
    Exposure2Intensity(0)
    
    def Intensity2Exposure(intensity):
        inarg = float(intensity)
        
        if inarg == 0:
            print("Exposure of zero intensity is undefined.")
            return
        
        if inarg < 1e-323:
            inarg = max(inarg, 1e-323)
            print("Exposure of negative intensities is undefined. Clamping to a very small value instead (1e-323)")
        
        result = math.log(inarg, 2)
        print(result)
    
    Intensity2Exposure(0.1)
    

    Why Exposure?

    Exposure is a stop value that multiplies the intensity by 2 to the power of the stop. Increasing exposure by 1 results in double the amount of light.

    Artists think in “stops.” Doubling or halving brightness is easy math and common in grading and look-dev.
    Exposure counts doublings in whole stops:

    • +1 stop = ×2 brightness
    • −1 stop = ×0.5 brightness

    This gives perceptually even controls across both bright and dark values.


    Why Intensity?

    Intensity is linear.
    It’s what render engines and compositors expect when:

    • Summing values
    • Averaging pixels
    • Multiplying or filtering pixel data

    Use intensity when you need the actual math on pixel/light data.


    Formulas (from your Python)

    • Intensity from exposure: intensity = 2**exposure
    • Exposure from intensity: exposure = log₂(intensity)

    Guardrails:

    • Intensity must be > 0 to compute exposure.
    • If intensity = 0 → exposure is undefined.
    • Clamp tiny values (e.g. 1e−323) before using log₂.

    Use Exposure (stops) when…

    • You want artist-friendly sliders (−5…+5 stops)
    • Adjusting look-dev or grading in even stops
    • Matching plates with quick ±1 stop tweaks
    • Tweening brightness changes smoothly across ranges

    Use Intensity (linear) when…

    • Storing raw pixel/light values
    • Multiplying textures or lights by a gain
    • Performing sums, averages, and filters
    • Feeding values to render engines expecting linear data

    Examples

    • +2 stops → 2**2 = 4.0 (×4)
    • +1 stop → 2**1 = 2.0 (×2)
    • 0 stop → 2**0 = 1.0 (×1)
    • −1 stop → 2**(−1) = 0.5 (×0.5)
    • −2 stops → 2**(−2) = 0.25 (×0.25)
    • Intensity 0.1 → exposure = log₂(0.1) ≈ −3.32

    Rule of thumb

    Think in stops (exposure) for controls and matching.
    Compute in linear (intensity) for rendering and math.