# 機能設計書 37-クロップ

## 概要

本ドキュメントは、StaxRipアプリケーションにおける映像のクロップ（切り抜き）機能の設計を記述する。

### 本機能の処理概要

クロップ機能は、映像の上下左右の端を指定したピクセル数だけ切り取る機能である。レターボックス（黒帯）の除去や、不要な領域のトリミングに使用される。自動クロップ検出、スマートクロップ、手動クロップの3つの方法を提供する。

**業務上の目的・背景**：映画やTV番組のソースには様々なアスペクト比の黒帯（レターボックス/ピラーボックス）が含まれることがある。これらを適切に除去することで、エンコード効率の向上（無駄なピクセルをエンコードしない）と、視聴体験の向上が実現できる。

**機能の利用シーン**：
- レターボックス（上下の黒帯）の除去
- ピラーボックス（左右の黒帯）の除去
- 不均一な黒帯（汚れ、ノイズを含む端）の除去
- 特定のアスペクト比への調整

**主要な処理内容**：
1. CropFormダイアログでのビジュアルクロップ設定
2. 自動クロップ検出（複数フレームをサンプリング）
3. スマートクロップ（目標アスペクト比に合わせて計算）
4. クロップ値のMod2/Mod16自動補正
5. AviSynth/VapourSynthスクリプトへのCropフィルタ出力

**関連システム・外部連携**：フレームサーバー（AviSynth+/VapourSynth）を通じた映像プレビュー。

**権限による制御**：特になし。すべてのユーザーが利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 3 | CropForm | 主画面 | クロップ値の設定、プレビュー、自動検出 |
| 1 | MainForm | 参照画面 | クロップボタン、Assistantでのクロップ推奨 |

## 機能種別

映像フィルタ / ユーザーインタラクション

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| p.CropLeft | Integer | Yes | 左側クロップ値（ピクセル） | >= 0, Mod2推奨 |
| p.CropTop | Integer | Yes | 上側クロップ値（ピクセル） | >= 0, Mod2推奨 |
| p.CropRight | Integer | Yes | 右側クロップ値（ピクセル） | >= 0, Mod2推奨 |
| p.CropBottom | Integer | Yes | 下側クロップ値（ピクセル） | >= 0, Mod2推奨 |
| p.AutoCorrectCropValues | Boolean | No | クロップ値の自動補正 | デフォルト: True |

### 入力データソース

- CropFormでのユーザー入力（マウス操作、キーボード操作）
- 自動クロップ検出によるサンプリング結果
- スマートクロップによる計算結果

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Cropフィルタ | スクリプト | AviSynth: Crop(left, top, -right, -bottom) |
| | | VapourSynth: core.std.Crop(clip, left, right, top, bottom) |

### 出力先

- p.Script.Filters内のCropカテゴリフィルタ

## 処理フロー

### 処理シーケンス

```
1. CropForm起動
   └─ クロップ用スクリプトの生成と同期

2. フレーム描画
   └─ VideoRenderer.Draw()でクロップ領域を視覚化

3. クロップ値設定方法
   ├─ マウスドラッグ: MouseCrop()で動的に設定
   ├─ キーボード: CropActiveSide()で選択辺をクロップ
   └─ 自動検出: RunAutoCrop()で複数フレームから計算

4. 値の補正
   └─ FixMod(): AutoCorrectCropValues=Trueの場合、偶数に補正

5. ダイアログ終了
   └─ クロップ値をp.CropXXXに反映

6. スクリプト生成
   └─ VideoScript.GetScript()でCropフィルタを出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[CropForm起動]
    B --> C[クロップ用スクリプト生成]
    C --> D[フレームサーバー起動]
    D --> E[フレーム表示]
    E --> F{操作選択}
    F -->|マウスドラッグ| G[MouseCrop]
    F -->|キーボード| H[CropActiveSide]
    F -->|自動検出| I[RunAutoCrop]
    F -->|スマートクロップ| J[SmartCrop]
    G --> K[クロップ値更新]
    H --> K
    I --> K
    J --> K
    K --> L{AutoCorrect?}
    L -->|Yes| M[FixMod: 偶数に補正]
    L -->|No| N[そのまま]
    M --> O[UpdateAll: 表示更新]
    N --> O
    O --> P{終了?}
    P -->|No| F
    P -->|Yes| Q[クロップ値をプロジェクトに保存]
    Q --> R[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-37-01 | Mod2補正 | AutoCorrectCropValues=Trueの場合、クロップ値を偶数に補正 | クロップ値設定時 |
| BR-37-02 | 最大クロップ制限 | クロップ値はソースサイズの80%以下 | UpdateAll時 |
| BR-37-03 | 自動検出サンプリング | 複数フレームをサンプリングして最適なクロップ値を計算 | RunAutoCrop時 |
| BR-37-04 | AviSynth形式 | Crop(left, top, -right, -bottom)形式で出力 | AviSynth使用時 |
| BR-37-05 | VapourSynth形式 | core.std.Crop(clip, left, right, top, bottom)形式で出力 | VapourSynth使用時 |

### 計算ロジック

**クロップ後サイズ計算**:
```
cropWidth = p.SourceWidth - p.CropLeft - p.CropRight
cropHeight = p.SourceHeight - p.CropTop - p.CropBottom
```

**Mod計算**:
```
Mod = GCD(cropWidth, cropHeight) の最小公約数をチェック
```

## データベース操作仕様

### 操作別データベース影響一覧

データベース操作なし（プロジェクトファイル内に保存）

### テーブル別操作詳細

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | スクリプトエラー | クロップ後サイズが不正 | CropForm終了時にエラー表示、継続確認 |
| - | 最大値超過 | クロップ値がソースの80%を超える | maxWidth/maxHeightで制限 |

### リトライ仕様

リトライ処理なし

## トランザクション仕様

ファイル操作のためトランザクション管理なし

## パフォーマンス要件

- フレーム描画はリアルタイムで行う
- 自動クロップ検出は進捗表示付きで実行

## セキュリティ考慮事項

特になし

## 備考

- クロップ値はマクロ（%crop_left%等）として他のフィルタで参照可能
- HDR映像のクロップ時はトーンマッピングオプションが利用可能

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

Projectクラスのクロップ関連プロパティを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Project.vb | `Source/General/Project.vb` | CropLeft, CropTop, CropRight, CropBottomプロパティ |
| 1-2 | Project.vb | `Source/General/Project.vb` | AutoCorrectCropValuesプロパティ |

**読解のコツ**: クロップ値はProjectオブジェクト（p）に保存され、シリアライズ対象。

#### Step 2: CropFormのUIを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | CropForm.vb | `Source/Forms/CropForm.vb` | InitializeComponent()（22-138行目） |
| 2-2 | CropForm.vb | `Source/Forms/CropForm.vb` | New()コンストラクタ（153-211行目） |

**主要処理フロー**:
- **153-155行目**: InitializeComponent、IsComposited設定
- **162-168行目**: CommandManagerとContextMenuの設定
- **206行目**: tbPosition.Maximum = p.SourceFrames

#### Step 3: クロップ処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | CropForm.vb | `Source/Forms/CropForm.vb` | CropActiveSideInternal()メソッド（349-378行目） |
| 3-2 | CropForm.vb | `Source/Forms/CropForm.vb` | MouseCrop()メソッド（406-427行目） |
| 3-3 | CropForm.vb | `Source/Forms/CropForm.vb` | FixMod()メソッド（459-465行目） |

**主要処理フロー**:
- **349-378行目**: Sideに応じてp.CropXXXを増減
- **406-427行目**: マウス位置からクロップ値を計算
- **459-465行目**: AutoCorrectCropValues時に偶数補正

#### Step 4: 自動クロップを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | CropForm.vb | `Source/Forms/CropForm.vb` | RunAutoCrop()メソッド（638-653行目） |
| 4-2 | GlobalClass.vb | `Source/General/GlobalClass.vb` | g.RunAutoCrop()（実装を参照） |

**主要処理フロー**:
- **638-644行目**: クロップ値を0にリセット
- **645-649行目**: g.RunAutoCropを進捗コールバック付きで実行
- **651-652行目**: 完了後にtbPosition.Value = 0

#### Step 5: 表示更新を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | CropForm.vb | `Source/Forms/CropForm.vb` | UpdateAll()メソッド（467-515行目） |

**主要処理フロー**:
- **468-485行目**: 最大クロップ値の制限
- **487-491行目**: Renderer.CropXXXにクロップ値設定
- **493-514行目**: ステータスバー表示の更新（Size, Mod, Error, DAR）

### プログラム呼び出し階層図

```
MainForm
    │
    └─ CropボタンまたはAssistant
           │
           └─ CropForm
                  │
                  ├─ OnLoad()
                  │      ├─ クロップ用スクリプト生成
                  │      ├─ FrameServer起動
                  │      └─ VideoRenderer初期化
                  │
                  ├─ マウス/キーボード入力
                  │      ├─ MouseCrop()
                  │      ├─ CropActiveSide()
                  │      └─ FixMod()
                  │
                  ├─ 自動クロップ
                  │      ├─ RunAutoCrop()
                  │      └─ g.RunAutoCrop()
                  │
                  ├─ スマートクロップ
                  │      └─ g.SmartCrop()
                  │
                  └─ UpdateAll()
                         ├─ 最大値制限
                         ├─ Renderer更新
                         └─ ステータス表示
```

### データフロー図

```
[入力]                          [処理]                              [出力]

マウス/キーボード ──────────────▶ CropForm ─────────────────────▶ p.CropLeft/Top/Right/Bottom
      │                               │
      │                               ▼
      │                         FixMod()
      │                               │
      │                               ▼
      │                      UpdateAll()
      │                               │
      │                    ┌──────────┴──────────┐
      │                    ▼                     ▼
      │              最大値制限            Renderer更新
      │                    │                     │
      │                    ▼                     │
      │              Calc.GetMod()               │
      │                    │                     │
      │                    ▼                     ▼
      │              ステータス表示         プレビュー描画
      │
      └────────────────────────────────────────────▶ VideoScript
                                                        │
                                                        ▼
                                                   Cropフィルタ
                                                        │
                                                   ┌────┴────┐
                                                   ▼         ▼
                                             AviSynth   VapourSynth
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| CropForm.vb | `Source/Forms/CropForm.vb` | ソース | クロップダイアログのメインクラス |
| Project.vb | `Source/General/Project.vb` | ソース | クロップ値プロパティの定義 |
| VideoScript.vb | `Source/Video/VideoScript.vb` | ソース | Cropフィルタの出力 |
| VideoRenderer.vb | `Source/Video/VideoRenderer.vb` | ソース | クロップ領域のプレビュー描画 |
| GlobalClass.vb | `Source/General/GlobalClass.vb` | ソース | g.RunAutoCrop(), g.SmartCrop() |
| Calc.vb | `Source/General/Calc.vb` | ソース | Mod計算、アスペクト比計算 |
