# DICOM Viewer Implementation

**Date**: 2025-01-12  
**Status**: Implemented  
**Version**: 0.1.0

## Overview

The DICOM viewer has been implemented using Cornerstone.js, a popular open-source library for medical imaging. The viewer supports full DICOM file rendering with interactive controls for zoom, pan, rotate, window/level adjustment, and image inversion.

## Implementation Details

### Technology Stack

- **Cornerstone.js** - Core DICOM rendering engine
- **cornerstone-wado-image-loader** - DICOM file parsing and loading
- **cornerstone-tools** - Interactive tools (pan, zoom, window/level, rotate)
- **dicom-parser** - DICOM metadata parsing
- **cornerstone-math** - Mathematical utilities for image processing

All libraries are loaded via CDN from jsDelivr for simplicity. The manifest.json includes a Content Security Policy to allow these external scripts.

### File Structure

```
src/viewers/dicom/
└── viewer.html  # Complete DICOM viewer implementation
```

### Features Implemented

#### ✅ Core Functionality
- DICOM file parsing and rendering
- Data URL and blob URL support (from download manager)
- Image display with proper windowing/leveling
- Canvas-based rendering with Cornerstone

#### ✅ Interactive Controls
- **Zoom In/Out** - Mouse wheel or toolbar buttons (+/- keys)
- **Pan** - Click and drag (left mouse button)
- **Window/Level** - Right-click drag for brightness/contrast adjustment
- **Rotate** - Toolbar buttons or arrow keys (left/right)
- **Invert** - Toggle image inversion (I key)
- **Fit to Screen** - Reset zoom to fit (0 key)
- **Reset** - Reset all transformations (R key)

#### ✅ UI Components
- Header with filename and action buttons
- Toolbar with visual controls
- Info panel showing DICOM metadata:
  - Patient name
  - Study date
  - Modality
  - Image dimensions
- Status bar showing:
  - Current zoom level
  - Window/Level values
  - Pan position

#### ✅ Keyboard Shortcuts
- `+` or `=` - Zoom in
- `-` or `_` - Zoom out
- `0` - Fit to screen
- `R` - Reset all
- `I` - Invert image
- `←` - Rotate left 90°
- `→` - Rotate right 90°
- `Esc` - Close viewer

### Integration with Download Manager

The viewer receives files via query parameter:
```
src/viewers/dicom/viewer.html?file={dataUrl}
```

The download manager (`src/background/downloads.js`) converts downloaded DICOM files to data URLs and opens them in the viewer:

```javascript
// From downloads.js getViewerUrl()
if (ext === 'dcm' || ext === 'dicom' || mime === 'application/dicom') {
  return chrome.runtime.getURL(
    `src/viewers/dicom/viewer.html?file=${encodeURIComponent(blobUrl)}`
  );
}
```

### Data Flow

1. User selects DICOM file in document browser
2. Download manager downloads file and stores in IndexedDB
3. File is converted to data URL (for files < 10MB)
4. Viewer URL is constructed with data URL as query parameter
5. New tab opens with viewer.html
6. Viewer extracts data URL from query params
7. Data URL is converted to File object
8. File is added to Cornerstone file manager
9. Cornerstone loads and renders DICOM image
10. User can interact with image using tools

### Code Structure

The viewer is implemented as a single HTML file with embedded JavaScript:

- **DicomViewer class** - Main controller
  - `initCornerstone()` - Initialize Cornerstone libraries
  - `setupUI()` - Set up event listeners and tools
  - `loadFile()` - Load and render DICOM file
  - `updateMetadata()` - Extract and display DICOM tags
  - `updateStatusBar()` - Update zoom/pan/window-level display
  - Control methods: `zoomIn()`, `zoomOut()`, `fitToScreen()`, `rotate()`, `toggleInvert()`, `reset()`

### DICOM Metadata Extraction

The viewer attempts to extract standard DICOM tags:
- `x00100010` - Patient Name
- `x00080020` - Study Date
- `x00080060` - Modality
- Image dimensions from Cornerstone image object

### Window/Level Calculation

If DICOM tags are available, window width and center are calculated from pixel value range:
```javascript
this.windowWidth = image.maxPixelValue - image.minPixelValue;
this.windowCenter = (image.maxPixelValue + image.minPixelValue) / 2;
```

### Error Handling

- Loading states with spinner
- Error messages for failed file loads
- Placeholder message if no file provided
- Console logging for debugging

## ⚠️ Important: Chrome MV3 Limitation

**Chrome MV3 blocks external scripts in extension pages.** The current CDN-based implementation will **not work** in MV3 because:

1. Extension pages (like `viewer.html` opened via `chrome.tabs.create`) cannot load external scripts
2. CSP cannot allow external URLs for `extension_pages`
3. CDN scripts will be blocked by browser security

**Solution**: Libraries must be bundled locally. See `DICOM_VIEWER_BUNDLING.md` for implementation steps.

**Current Status**: The viewer HTML is ready, but libraries need to be bundled locally before it will function.

## Testing

### Manual Testing Checklist

- [ ] DICOM file downloads successfully
- [ ] Viewer opens automatically after download
- [ ] Image renders correctly
- [ ] Zoom controls work (buttons and mouse wheel)
- [ ] Pan works (click and drag)
- [ ] Window/Level adjustment works (right-click drag)
- [ ] Rotate buttons work
- [ ] Invert toggle works
- [ ] Reset button restores original view
- [ ] Keyboard shortcuts work
- [ ] DICOM metadata displays correctly
- [ ] Status bar updates correctly
- [ ] Download button saves file

### Known Limitations

1. **Large Files**: Files > 10MB may not work with data URLs (fallback to chrome.downloads API)
2. **Multi-frame DICOM**: Currently only displays first frame (multi-frame support can be added)
3. **Measurement Tools**: Not yet implemented (ruler, angle measurements)
4. **CDN Dependency**: Requires internet connection for CDN scripts (can be bundled locally later)

## Future Enhancements

### Phase 2 Features (Not Yet Implemented)
- [ ] Multi-frame DICOM support (series navigation)
- [ ] Measurement tools (ruler, angle, ROI)
- [ ] Annotation tools
- [ ] Comparison view (side-by-side)
- [ ] Export functionality (screenshot, annotations)
- [ ] Local library bundling (remove CDN dependency)

## Troubleshooting

### Viewer Shows Placeholder
- Check browser console for errors
- Verify CDN scripts loaded (check Network tab)
- Check CSP errors in console

### Image Doesn't Render
- Verify file is valid DICOM format
- Check console for Cornerstone errors
- Try with a known-good DICOM file

### Tools Don't Work
- Verify Cornerstone tools initialized
- Check that element is enabled: `cornerstone.enable(element)`
- Verify tools are attached to element

### Data URL Too Large
- Files > 10MB may fail - check download manager logs
- Consider using blob URLs instead (requires different approach)

## Related Files

- `src/viewers/dicom/viewer.html` - Main viewer implementation
- `src/viewers/registry.js` - Viewer registration (routes DICOM files to viewer)
- `src/background/downloads.js` - Download manager (creates viewer URLs)
- `manifest.json` - CSP configuration for CDN scripts

## References

- [Cornerstone.js Documentation](https://cornerstonejs.org/)
- [Cornerstone Tools Documentation](https://tools.cornerstonejs.org/)
- [DICOM Standard](https://www.dicomstandard.org/)
