-
Notifications
You must be signed in to change notification settings - Fork 0
/
ImageLines.cs
98 lines (92 loc) · 4.31 KB
/
ImageLines.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
using Hjg.Pngcs;
using System;
using System.Collections.Generic;
using System.Text;
namespace Hjg.Pngcs {
/// <summary>
/// Wraps a set of rows from a image, read in a single operation, stored in a int[][] or byte[][] matrix
///
/// They can be a subset of the total rows, but in this case they are equispaced.
///
/// See also ImageLine
/// </summary>
public class ImageLines {
public ImageInfo ImgInfo {get; private set;}
public ImageLine.ESampleType sampleType { get; private set; }
public bool SamplesUnpacked { get; private set; }
public int RowOffset { get; private set; }
public int Nrows { get; private set; }
public int RowStep { get; private set; }
internal readonly int channels;
internal readonly int bitDepth;
internal readonly int elementsPerRow;
public int[][] Scanlines { get; private set; }
public byte[][] ScanlinesB { get; private set; }
public ImageLines(global::Hjg.Pngcs.ImageInfo ImgInfo, global::Hjg.Pngcs.ImageLine.ESampleType sampleType, bool unpackedMode, int rowOffset, int nRows, int rowStep) {
this.ImgInfo = ImgInfo;
channels = ImgInfo.Channels;
bitDepth = ImgInfo.BitDepth;
this.sampleType = sampleType;
this.SamplesUnpacked = unpackedMode || !ImgInfo.Packed;
this.RowOffset = rowOffset;
this.Nrows = nRows;
this.RowStep = rowStep;
elementsPerRow = unpackedMode ? ImgInfo.SamplesPerRow : ImgInfo.SamplesPerRowPacked;
if (sampleType == ImageLine.ESampleType.INT) {
Scanlines = new int[nRows][];
for (int i = 0; i < nRows; i++) Scanlines[i] = new int[elementsPerRow];
ScanlinesB = null;
} else if (sampleType == ImageLine.ESampleType.BYTE) {
ScanlinesB = new byte[nRows][];
for (int i = 0; i < nRows; i++) ScanlinesB[i] = new byte[elementsPerRow];
Scanlines = null;
} else
throw new PngjExceptionInternal("bad ImageLine initialization");
}
/// <summary>
/// Translates from image row number to matrix row.
/// If you are not sure if this image row in included, use better ImageRowToMatrixRowStrict
///
/// </summary>
/// <param name="imrow">Row number in the original image (from 0) </param>
/// <returns>Row number in the wrapped matrix. Undefined result if invalid</returns>
public int ImageRowToMatrixRow(int imrow) {
int r = (imrow - RowOffset) / RowStep;
return r < 0 ? 0 : (r < Nrows ? r : Nrows - 1);
}
/// <summary>
/// translates from image row number to matrix row
/// </summary>
/// <param name="imrow">Row number in the original image (from 0) </param>
/// <returns>Row number in the wrapped matrix. Returns -1 if invalid</returns>
public int ImageRowToMatrixRowStrict(int imrow) {
imrow -= RowOffset;
int mrow = imrow >= 0 && imrow % RowStep == 0 ? imrow / RowStep : -1;
return mrow < Nrows ? mrow : -1;
}
/// <summary>
/// Translates from matrix row number to real image row number
/// </summary>
/// <param name="mrow"></param>
/// <returns></returns>
public int MatrixRowToImageRow(int mrow) {
return mrow * RowStep + RowOffset;
}
/// <summary>
/// Constructs and returns an ImageLine object backed by a matrix row.
/// This is quite efficient, no deep copy.
/// </summary>
/// <param name="mrow">Row number inside the matrix</param>
/// <returns></returns>
public ImageLine GetImageLineAtMatrixRow(int mrow) {
if (mrow < 0 || mrow > Nrows)
throw new PngjException("Bad row " + mrow + ". Should be positive and less than "
+ Nrows);
ImageLine imline = sampleType == ImageLine.ESampleType.INT ? new ImageLine(ImgInfo, sampleType,
SamplesUnpacked, Scanlines[mrow], null) : new ImageLine(ImgInfo, sampleType,
SamplesUnpacked, null, ScanlinesB[mrow]);
imline.Rown = MatrixRowToImageRow(mrow);
return imline;
}
}
}