diff --git a/docs/ai.generated/01-system-overview.md b/docs/ai.generated/01-system-overview.md index 7be9d735..d4d48162 100644 --- a/docs/ai.generated/01-system-overview.md +++ b/docs/ai.generated/01-system-overview.md @@ -3,7 +3,7 @@ ## DoczyAI Document Processing Platform ### Purpose and Domain -DoczyAI is a cloud-native document processing platform for multi-tenant PDF ingestion and processing. Organizations can upload and organize documents with folders and labels, and store structured field extraction results for downstream analysis. +DoczyAI is a cloud-native document processing platform for multi-tenant document ingestion and processing. The system supports a wide range of file types including PDF, images (TIFF, JPEG, PNG, BMP), Office documents (DOCX, XLSX, PPTX), plain text, and email (EML). Organizations can upload and organize documents with folders and labels, and store structured field extraction results for downstream analysis. ### Core Business Capabilities - **Multi-tenant Document Processing**: Isolated processing environments per client diff --git a/docs/ai.generated/03-api-documentation.md b/docs/ai.generated/03-api-documentation.md index 18979907..9eaefee5 100644 --- a/docs/ai.generated/03-api-documentation.md +++ b/docs/ai.generated/03-api-documentation.md @@ -327,7 +327,7 @@ Uploads a document for a specific client. **Form Parameters**: -- `file` (required): Document file (PDF) +- `file` (required): Document file. Accepted types: PDF, TIFF, JPEG, PNG, BMP, DOCX, XLSX, PPTX, TXT, EML - `filename` (optional): Custom filename (max 4096 chars) **Response**: `200` Document uploaded @@ -463,16 +463,20 @@ Permanently deletes a document and all dependent data: document entries, cleans ### `POST /client/{id}/document/batch` -Uploads a ZIP archive containing multiple PDF documents for asynchronous batch processing. +Uploads a ZIP archive containing multiple documents for asynchronous batch processing. **Security**: Requires JWT authentication **Content Type**: `multipart/form-data` **Max Archive Size**: 1GB **Supported Archive Type**: ZIP only +**Accepted File Extensions**: `.pdf`, `.tiff`, `.tif`, `.jpeg`, `.jpg`, `.png`, `.bmp`, `.docx`, `.xlsx`, `.pptx`, `.txt`, `.eml` + +Note: Macro-enabled Office formats (`.docm`, `.xlsm`, `.pptm`) are intentionally excluded because documents containing macros are rejected during validation. + **Form Parameters**: -- `archive` (required): ZIP file containing PDF documents +- `archive` (required): ZIP file containing documents **Response** (`202 Accepted`): @@ -578,7 +582,7 @@ Retrieves detailed status information for a specific batch upload, including per "updated_at": "2024-01-01T00:04:55Z" }, { - "filename": "spreadsheet.xlsx", + "filename": "macro_enabled.xlsm", "outcome": "invalid_type", "error_detail": null, "document_id": null, @@ -601,7 +605,7 @@ The `document_outcomes` array provides per-file tracking through the entire proc | `failed_read` | Could not read file content from ZIP archive | Yes | | `failed_s3_upload` | Could not upload extracted file to S3 | Yes | | `failed_upload` | Upload handler returned an error | Yes | -| `invalid_type` | File is not a PDF | Yes | +| `invalid_type` | File type is not in the accepted extensions list | Yes | | `init_complete` | Document record created, forwarded to sync | No | | `init_duplicate` | Duplicate detected during init processing | Yes | | `sync_complete` | Sync check passed, forwarded to clean | No | diff --git a/docs/ai.generated/04-data-architecture.md b/docs/ai.generated/04-data-architecture.md index 2c3f7a38..e0b718ea 100644 --- a/docs/ai.generated/04-data-architecture.md +++ b/docs/ai.generated/04-data-architecture.md @@ -1049,7 +1049,7 @@ CREATE TABLE documentEntries ( - Multiple entries possible per document for version tracking #### Document Cleans (`documentCleans`) -PDF validation and format processing records. +Document validation and format processing records. ```sql CREATE TYPE cleanFailType AS ENUM ( @@ -1061,10 +1061,27 @@ CREATE TYPE cleanFailType AS ENUM ( 'small_dimensions', 'large_dimensions', 'small_dpi', - 'large_dpi' + 'large_dpi', + 'password_protected', + 'contains_macros', + 'empty_content', + 'binary_content', + 'unsupported_encoding', + 'contains_attachments' ); -CREATE TYPE cleanMimeType AS ENUM ('application/pdf'); +CREATE TYPE cleanMimeType AS ENUM ( + 'application/pdf', + 'image/tiff', + 'image/jpeg', + 'image/png', + 'image/bmp', + 'application/docx', + 'application/xlsx', + 'application/pptx', + 'text/plain', + 'message/rfc822' +); CREATE TABLE documentCleans ( id uuid PRIMARY KEY DEFAULT uuid_generate_v7(), @@ -1091,6 +1108,33 @@ CREATE TABLE documentCleans ( - Cannot have both success and failure indicators - Tracks specific failure reasons for troubleshooting +**Supported MIME Types**: +- `application/pdf` -- PDF documents +- `image/tiff` -- TIFF images (multi-frame supported) +- `image/jpeg` -- JPEG images +- `image/png` -- PNG images +- `image/bmp` -- BMP images +- `application/docx` -- Word documents +- `application/xlsx` -- Excel spreadsheets +- `application/pptx` -- PowerPoint presentations +- `text/plain` -- Plain text files +- `message/rfc822` -- Email messages (EML) + +**Failure Reasons**: +- `invalid_mimetype` -- Unrecognized or unsupported content type +- `invalid_read` -- Could not read document content +- `invalid_read_pages` -- Could not read individual pages +- `zero_page_count` -- Document has no pages/sheets/slides +- `large_file` -- File exceeds size limit (500MB for images/Office, 100MB for text/email) +- `small_dimensions` / `large_dimensions` -- Image dimensions outside acceptable range +- `small_dpi` / `large_dpi` -- Image resolution outside acceptable range (min 72 DPI) +- `password_protected` -- Document is encrypted or password-protected (DOCX, XLSX, PPTX, OLE2) +- `contains_macros` -- Document contains VBA macros (DOCX, XLSX, PPTX) +- `empty_content` -- Document has no meaningful content (blank images, empty text) +- `binary_content` -- Text file contains binary data (null bytes) +- `unsupported_encoding` -- Text file uses an unsupported character encoding +- `contains_attachments` -- Email contains MIME attachments (only plain text emails accepted) + #### Document Clean Entries (`documentCleanEntries`) Version tracking for clean operations. diff --git a/docs/ai.generated/README.md b/docs/ai.generated/README.md index 08bd5f91..d043432b 100644 --- a/docs/ai.generated/README.md +++ b/docs/ai.generated/README.md @@ -106,7 +106,7 @@ This documentation provides comprehensive coverage of the DoczyAI Document Proce - **Monitoring**: Prometheus + OpenTelemetry ### 📊 Key Capabilities -- **Document Processing**: PDF upload, download, initialization, sync-gating, and cleaning +- **Document Processing**: Multi-format document upload (PDF, TIFF, JPEG, PNG, BMP, DOCX, XLSX, PPTX, TXT, EML), download, initialization, sync-gating, and cleaning - **Multi-tenant Support**: Isolated client environments - **Document Organization**: Folders and labels for document management - **Export Operations**: Structured data export in multiple formats diff --git a/docs/ai.generated/batch-outcome-tracking-guide.md b/docs/ai.generated/batch-outcome-tracking-guide.md index 9e27793c..8cf10d61 100644 --- a/docs/ai.generated/batch-outcome-tracking-guide.md +++ b/docs/ai.generated/batch-outcome-tracking-guide.md @@ -6,7 +6,7 @@ For API reference details, see [API Documentation - Batch Document Operations](. ## 1. Upload a Batch -Submit a ZIP archive containing PDF documents for batch processing. +Submit a ZIP archive containing documents for batch processing. Accepted file types: PDF, TIFF, JPEG, PNG, BMP, DOCX, XLSX, PPTX, TXT, EML. ``` POST /client/AAA/document/batch @@ -86,7 +86,7 @@ Once ZIP extraction finishes, `status` changes to `completed` and all files appe "document_id": "...0003" }, { - "filename": "spreadsheet.xlsx", + "filename": "macro_report.xlsm", "outcome": "invalid_type", "document_id": null } @@ -126,7 +126,7 @@ When all documents have reached a terminal outcome, the batch is fully processed "clean_fail_reason": "invalid PDF structure: missing xref table" }, { - "filename": "spreadsheet.xlsx", + "filename": "macro_report.xlsm", "outcome": "invalid_type", "document_id": null } @@ -142,9 +142,9 @@ Each terminal outcome indicates a specific action for the caller: - **`duplicate`** -- The file hash matches a document already in the system for this client. Use the returned `document_id` to reference the existing document. No resubmission needed. -- **`clean_failed`** -- The PDF was corrupt or failed validation. Check `clean_fail_reason` for the specific failure detail. Fix the source file and resubmit. +- **`clean_failed`** -- The document was corrupt or failed validation. Check `clean_fail_reason` for the specific failure detail. Possible reasons include `invalid_mimetype`, `password_protected`, `contains_macros`, `empty_content`, `binary_content`, `unsupported_encoding`, `contains_attachments`, dimension/DPI issues, and more. Fix the source file and resubmit. -- **`invalid_type`** -- The file is not a PDF. Only PDF files are accepted. +- **`invalid_type`** -- The file extension is not in the accepted list. Accepted extensions: `.pdf`, `.tiff`, `.tif`, `.jpeg`, `.jpg`, `.png`, `.bmp`, `.docx`, `.xlsx`, `.pptx`, `.txt`, `.eml`. Macro-enabled formats (`.docm`, `.xlsm`, `.pptm`) are not accepted. - **`failed_open`** / **`failed_read`** -- The file inside the ZIP was damaged or unreadable. Re-create the ZIP archive and resubmit. @@ -161,7 +161,7 @@ Each file in a batch starts at extraction and progresses through the document pr ``` ZIP extracted | - +-- invalid_type (not PDF) .............. TERMINAL + +-- invalid_type (unsupported ext) ....... TERMINAL +-- failed_open / failed_read ........... TERMINAL +-- failed_s3_upload / failed_upload .... TERMINAL +-- duplicate (hash match) .............. TERMINAL diff --git a/go.mod b/go.mod index 1295cee7..e0e792f0 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,8 @@ require ( github.com/aws/aws-sdk-go-v2/service/s3 v1.78.1 github.com/aws/aws-sdk-go-v2/service/sqs v1.38.1 github.com/caarlos0/env/v11 v11.3.1 + github.com/chai2010/tiff v0.0.0-20211005095045-4ec2aa243943 + github.com/dimchansky/utfbom v1.1.1 github.com/getkin/kin-openapi v0.129.0 github.com/go-playground/validator/v10 v10.25.0 github.com/golang-migrate/migrate/v4 v4.18.2 @@ -26,11 +28,15 @@ require ( github.com/pdfcpu/pdfcpu v0.9.1 github.com/permitio/permit-golang v1.2.5 github.com/prometheus/client_golang v1.21.1 + github.com/richardlehane/mscfb v1.0.6 + github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd + github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d github.com/stretchr/testify v1.10.0 github.com/swaggo/echo-swagger v1.4.1 github.com/testcontainers/testcontainers-go v0.35.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 go.opentelemetry.io/otel/sdk v1.34.0 + golang.org/x/image v0.25.0 golang.org/x/time v0.11.0 ) @@ -94,6 +100,7 @@ require ( github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.62.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect + github.com/richardlehane/msoleps v1.0.3 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/rs/zerolog v1.33.0 // indirect github.com/sagikazarmark/locafero v0.7.0 // indirect @@ -119,7 +126,6 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac // indirect - golang.org/x/image v0.25.0 // indirect golang.org/x/mod v0.23.0 // indirect golang.org/x/oauth2 v0.27.0 // indirect golang.org/x/sync v0.12.0 // indirect diff --git a/go.sum b/go.sum index 49b05483..1efb2d35 100644 --- a/go.sum +++ b/go.sum @@ -62,6 +62,8 @@ github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK3 github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chai2010/tiff v0.0.0-20211005095045-4ec2aa243943 h1:CjuhVIUiyWQZVY4rmcvm/9R+60e/Wi6LkXyHU38MqXI= +github.com/chai2010/tiff v0.0.0-20211005095045-4ec2aa243943/go.mod h1:FhMMqekobM33oGdTfbi65oQ9P7bnQ5/0EDfmleW35RE= github.com/chigopher/pathlib v0.19.1 h1:RoLlUJc0CqBGwq239cilyhxPNLXTK+HXoASGyGznx5A= github.com/chigopher/pathlib v0.19.1/go.mod h1:tzC1dZLW8o33UQpWkNkhvPwL5n4yyFRFm/jL1YGWFvY= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= @@ -82,6 +84,8 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvw github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= github.com/dhui/dktest v0.4.4 h1:+I4s6JRE1yGuqflzwqG+aIaMdgXIorCf5P98JnaAWa8= github.com/dhui/dktest v0.4.4/go.mod h1:4+22R4lgsdAXrDyaH4Nqx2JEz2hLp49MqQmm9HLCQhM= +github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U= +github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/docker/docker v28.0.1+incompatible h1:FCHjSRdXhNRFjlHMTv4jUNlIBbTeRjrWfeFuJp7jpo0= @@ -285,6 +289,10 @@ github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/richardlehane/mscfb v1.0.6 h1:eN3bvvZCp00bs7Zf52bxNwAx5lJDBK1tCuH19qq5aC8= +github.com/richardlehane/mscfb v1.0.6/go.mod h1:pe0+IUIc0AHh0+teNzBlJCtSyZdFOGgV4ZK9bsoV+Jo= +github.com/richardlehane/msoleps v1.0.3 h1:aznSZzrwYRl3rLKRT3gUk9am7T/mLNSnJINvN0AQoVM= +github.com/richardlehane/msoleps v1.0.3/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= @@ -294,10 +302,14 @@ github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd h1:CmH9+J6ZSsIjUK3dcGsnCnO41eRBOnY12zwkn5qVwgc= +github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsFaodPcyo= github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= +github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d h1:hrujxIzL1woJ7AwssoOcM/tq5JjjG2yYOc8odClEiXA= +github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU= github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI= diff --git a/internal/database/migrations/00000000000125_multiformat_support.down.sql b/internal/database/migrations/00000000000125_multiformat_support.down.sql new file mode 100644 index 00000000..294ad699 --- /dev/null +++ b/internal/database/migrations/00000000000125_multiformat_support.down.sql @@ -0,0 +1,5 @@ +-- PostgreSQL does not support removing enum values directly. +-- To reverse this migration, the enum types would need to be recreated. +-- This is intentionally left as a no-op since removing enum values +-- requires recreating the type and all dependent columns. +-- In practice, these enum values are safe to leave in place. diff --git a/internal/database/migrations/00000000000125_multiformat_support.up.sql b/internal/database/migrations/00000000000125_multiformat_support.up.sql new file mode 100644 index 00000000..3c789d42 --- /dev/null +++ b/internal/database/migrations/00000000000125_multiformat_support.up.sql @@ -0,0 +1,18 @@ +-- Add new MIME types for multi-format document support +ALTER TYPE cleanMimeType ADD VALUE IF NOT EXISTS 'image/tiff'; +ALTER TYPE cleanMimeType ADD VALUE IF NOT EXISTS 'image/jpeg'; +ALTER TYPE cleanMimeType ADD VALUE IF NOT EXISTS 'image/png'; +ALTER TYPE cleanMimeType ADD VALUE IF NOT EXISTS 'image/bmp'; +ALTER TYPE cleanMimeType ADD VALUE IF NOT EXISTS 'application/docx'; +ALTER TYPE cleanMimeType ADD VALUE IF NOT EXISTS 'application/xlsx'; +ALTER TYPE cleanMimeType ADD VALUE IF NOT EXISTS 'application/pptx'; +ALTER TYPE cleanMimeType ADD VALUE IF NOT EXISTS 'text/plain'; +ALTER TYPE cleanMimeType ADD VALUE IF NOT EXISTS 'message/rfc822'; + +-- Add new failure reasons for multi-format validation +ALTER TYPE cleanFailType ADD VALUE IF NOT EXISTS 'password_protected'; +ALTER TYPE cleanFailType ADD VALUE IF NOT EXISTS 'contains_macros'; +ALTER TYPE cleanFailType ADD VALUE IF NOT EXISTS 'empty_content'; +ALTER TYPE cleanFailType ADD VALUE IF NOT EXISTS 'binary_content'; +ALTER TYPE cleanFailType ADD VALUE IF NOT EXISTS 'unsupported_encoding'; +ALTER TYPE cleanFailType ADD VALUE IF NOT EXISTS 'contains_attachments'; diff --git a/internal/database/queries/batch.sql b/internal/database/queries/batch.sql index 91f77b0c..5cf0c8b8 100644 --- a/internal/database/queries/batch.sql +++ b/internal/database/queries/batch.sql @@ -38,10 +38,13 @@ WHERE client_id = $1 ORDER BY created_at DESC LIMIT $2 OFFSET $3; +-- name: SetBatchTotalDocuments :exec +UPDATE batch_uploads SET total_documents = $2 WHERE id = $1; + -- name: UpdateBatchProgress :exec -UPDATE batch_uploads -SET processed_documents = $2, - failed_documents = $3, +UPDATE batch_uploads +SET processed_documents = $2, + failed_documents = $3, invalid_type_documents = $4, progress_percent = $5 WHERE id = $1; diff --git a/internal/database/repository/batch.sql.go b/internal/database/repository/batch.sql.go index 7745e241..b28b960a 100644 --- a/internal/database/repository/batch.sql.go +++ b/internal/database/repository/batch.sql.go @@ -568,6 +568,23 @@ func (q *Queries) ResolveBatchDocumentOutcome(ctx context.Context, arg *ResolveB return err } +const setBatchTotalDocuments = `-- name: SetBatchTotalDocuments :exec +UPDATE batch_uploads SET total_documents = $2 WHERE id = $1 +` + +type SetBatchTotalDocumentsParams struct { + ID uuid.UUID `db:"id"` + TotalDocuments int32 `db:"total_documents"` +} + +// SetBatchTotalDocuments +// +// UPDATE batch_uploads SET total_documents = $2 WHERE id = $1 +func (q *Queries) SetBatchTotalDocuments(ctx context.Context, arg *SetBatchTotalDocumentsParams) error { + _, err := q.db.Exec(ctx, setBatchTotalDocuments, arg.ID, arg.TotalDocuments) + return err +} + const updateBatchDocumentOutcomeByDocumentID = `-- name: UpdateBatchDocumentOutcomeByDocumentID :exec UPDATE batch_document_outcomes SET outcome = $2::batch_outcome_status, @@ -600,9 +617,9 @@ func (q *Queries) UpdateBatchDocumentOutcomeByDocumentID(ctx context.Context, ar } const updateBatchProgress = `-- name: UpdateBatchProgress :exec -UPDATE batch_uploads -SET processed_documents = $2, - failed_documents = $3, +UPDATE batch_uploads +SET processed_documents = $2, + failed_documents = $3, invalid_type_documents = $4, progress_percent = $5 WHERE id = $1 diff --git a/internal/database/repository/models.go b/internal/database/repository/models.go index 540f6474..f5acf815 100644 --- a/internal/database/repository/models.go +++ b/internal/database/repository/models.go @@ -143,15 +143,21 @@ func (e BatchStatus) Valid() bool { type Cleanfailtype string const ( - CleanfailtypeInvalidMimetype Cleanfailtype = "invalid_mimetype" - CleanfailtypeInvalidRead Cleanfailtype = "invalid_read" - CleanfailtypeInvalidReadPages Cleanfailtype = "invalid_read_pages" - CleanfailtypeZeroPageCount Cleanfailtype = "zero_page_count" - CleanfailtypeLargeFile Cleanfailtype = "large_file" - CleanfailtypeSmallDimensions Cleanfailtype = "small_dimensions" - CleanfailtypeLargeDimensions Cleanfailtype = "large_dimensions" - CleanfailtypeSmallDpi Cleanfailtype = "small_dpi" - CleanfailtypeLargeDpi Cleanfailtype = "large_dpi" + CleanfailtypeInvalidMimetype Cleanfailtype = "invalid_mimetype" + CleanfailtypeInvalidRead Cleanfailtype = "invalid_read" + CleanfailtypeInvalidReadPages Cleanfailtype = "invalid_read_pages" + CleanfailtypeZeroPageCount Cleanfailtype = "zero_page_count" + CleanfailtypeLargeFile Cleanfailtype = "large_file" + CleanfailtypeSmallDimensions Cleanfailtype = "small_dimensions" + CleanfailtypeLargeDimensions Cleanfailtype = "large_dimensions" + CleanfailtypeSmallDpi Cleanfailtype = "small_dpi" + CleanfailtypeLargeDpi Cleanfailtype = "large_dpi" + CleanfailtypePasswordProtected Cleanfailtype = "password_protected" + CleanfailtypeContainsMacros Cleanfailtype = "contains_macros" + CleanfailtypeEmptyContent Cleanfailtype = "empty_content" + CleanfailtypeBinaryContent Cleanfailtype = "binary_content" + CleanfailtypeUnsupportedEncoding Cleanfailtype = "unsupported_encoding" + CleanfailtypeContainsAttachments Cleanfailtype = "contains_attachments" ) func (e *Cleanfailtype) Scan(src interface{}) error { @@ -199,7 +205,13 @@ func (e Cleanfailtype) Valid() bool { CleanfailtypeSmallDimensions, CleanfailtypeLargeDimensions, CleanfailtypeSmallDpi, - CleanfailtypeLargeDpi: + CleanfailtypeLargeDpi, + CleanfailtypePasswordProtected, + CleanfailtypeContainsMacros, + CleanfailtypeEmptyContent, + CleanfailtypeBinaryContent, + CleanfailtypeUnsupportedEncoding, + CleanfailtypeContainsAttachments: return true } return false @@ -208,7 +220,16 @@ func (e Cleanfailtype) Valid() bool { type Cleanmimetype string const ( - CleanmimetypeApplicationPdf Cleanmimetype = "application/pdf" + CleanmimetypeApplicationPdf Cleanmimetype = "application/pdf" + CleanmimetypeImageTiff Cleanmimetype = "image/tiff" + CleanmimetypeImageJpeg Cleanmimetype = "image/jpeg" + CleanmimetypeImagePng Cleanmimetype = "image/png" + CleanmimetypeImageBmp Cleanmimetype = "image/bmp" + CleanmimetypeApplicationDocx Cleanmimetype = "application/docx" + CleanmimetypeApplicationXlsx Cleanmimetype = "application/xlsx" + CleanmimetypeApplicationPptx Cleanmimetype = "application/pptx" + CleanmimetypeTextPlain Cleanmimetype = "text/plain" + CleanmimetypeMessageRfc822 Cleanmimetype = "message/rfc822" ) func (e *Cleanmimetype) Scan(src interface{}) error { @@ -248,7 +269,16 @@ func (ns NullCleanmimetype) Value() (driver.Value, error) { func (e Cleanmimetype) Valid() bool { switch e { - case CleanmimetypeApplicationPdf: + case CleanmimetypeApplicationPdf, + CleanmimetypeImageTiff, + CleanmimetypeImageJpeg, + CleanmimetypeImagePng, + CleanmimetypeImageBmp, + CleanmimetypeApplicationDocx, + CleanmimetypeApplicationXlsx, + CleanmimetypeApplicationPptx, + CleanmimetypeTextPlain, + CleanmimetypeMessageRfc822: return true } return false diff --git a/internal/document/batch/service.go b/internal/document/batch/service.go index d634d06c..068954d6 100644 --- a/internal/document/batch/service.go +++ b/internal/document/batch/service.go @@ -141,6 +141,10 @@ func (s *Service) Get(ctx context.Context, clientID string, batchID uuid.UUID) ( } details.DocumentOutcomes = outcomes + // Derive summary counts from actual outcome states rather than + // the extraction-phase counters stored in batch_uploads. + s.deriveSummaryCounts(details) + return details, nil } @@ -197,6 +201,23 @@ func (s *Service) UpdateProgress(ctx context.Context, clientID string, batchID u }) } +// SetTotalDocuments updates the total document count for a batch. +// Called after ZIP extraction when the actual file count is known. +// +// Parameters: +// - ctx: request context +// - batchID: the batch UUID +// - total: the total number of files extracted from the ZIP +// +// Returns: +// - error: database error, or nil +func (s *Service) SetTotalDocuments(ctx context.Context, batchID uuid.UUID, total int32) error { + return s.cfg.GetDBQueries().SetBatchTotalDocuments(ctx, &repository.SetBatchTotalDocumentsParams{ + ID: batchID, + TotalDocuments: total, + }) +} + // UpdateStatus updates the status of a batch func (s *Service) UpdateStatus(ctx context.Context, batchID uuid.UUID, status string) error { // Convert string status to repository.BatchStatus @@ -407,6 +428,49 @@ func (s *Service) CheckDuplicate(ctx context.Context, clientID string, hash stri return &id, nil } +// deriveSummaryCounts recomputes ProcessedDocuments, FailedDocuments, and +// InvalidTypeDocuments from the actual document outcome states. This ensures the +// summary reflects final pipeline results rather than extraction-phase counters. +// +// Terminal outcome bucketing: +// +// processed: clean_passed, sync_skipped, duplicate, init_duplicate +// failed: clean_failed, failed_open, failed_read, failed_s3_upload, failed_upload +// invalid_type: invalid_type +// in-progress: submitted, init_complete, sync_complete (not expected at completion) +func (s *Service) deriveSummaryCounts(details *BatchUploadDetails) { + if len(details.DocumentOutcomes) == 0 { + return + } + + var processed, failed, invalidType int32 + for _, o := range details.DocumentOutcomes { + switch o.Outcome { + case "clean_passed", "sync_skipped", "duplicate", "init_duplicate": + processed++ + case "clean_failed", "failed_open", "failed_read", + "failed_s3_upload", "failed_upload": + failed++ + case "invalid_type": + invalidType++ + default: + // Non-terminal states (submitted, init_complete, sync_complete) + // are in-progress; don't count them in any bucket. + } + } + + details.ProcessedDocuments = processed + details.FailedDocuments = failed + details.InvalidTypeDocuments = invalidType + + // Recalculate progress percent from derived counts + total := details.TotalDocuments + if total > 0 { + done := processed + failed + invalidType + details.ProgressPercent = int32(float64(done) / float64(total) * 100) + } +} + // ListUnprocessed retrieves all unprocessed batch uploads across all clients func (s *Service) ListUnprocessed(ctx context.Context) ([]*BatchUploadSummary, error) { batches, err := s.cfg.GetDBQueries().GetUnprocessedBatches(ctx) diff --git a/internal/document/batch/service_test.go b/internal/document/batch/service_test.go index 76d82827..38667d18 100644 --- a/internal/document/batch/service_test.go +++ b/internal/document/batch/service_test.go @@ -716,6 +716,88 @@ func TestListOutcomes_WithCleanFail(t *testing.T) { assert.Equal(t, "invalid_mimetype", *outcomes[0].CleanFail) } +func TestSetTotalDocuments(t *testing.T) { + cfg := &TestConfig{} + test.CreateDB(t, cfg) + + service := documentbatch.New(cfg) + ctx := t.Context() + + // Create test client + clientID := "test_client_set_total" + err := cfg.GetDBQueries().CreateClient(ctx, &repository.CreateClientParams{ + Clientid: clientID, + Name: "Test Client Set Total", + }) + require.NoError(t, err) + + // Create batch with totalDocs=0 + batchID, err := service.Create(ctx, clientID, "test.zip", 0) + require.NoError(t, err) + + // Set total documents to 15 + err = service.SetTotalDocuments(ctx, batchID, 15) + require.NoError(t, err) + + // Fetch and assert TotalDocuments == 15 + batch, err := cfg.GetDBQueries().GetBatchUpload(ctx, &repository.GetBatchUploadParams{ + ID: batchID, + ClientID: clientID, + }) + require.NoError(t, err) + assert.Equal(t, int32(15), batch.TotalDocuments) + + // Update progress and verify all fields + err = service.UpdateProgress(ctx, clientID, batchID, 10, 3, 2) + require.NoError(t, err) + + batch, err = cfg.GetDBQueries().GetBatchUpload(ctx, &repository.GetBatchUploadParams{ + ID: batchID, + ClientID: clientID, + }) + require.NoError(t, err) + assert.Equal(t, int32(10), batch.ProcessedDocuments) + assert.Equal(t, int32(3), batch.FailedDocuments) + assert.Equal(t, int32(2), batch.InvalidTypeDocuments) + assert.Equal(t, int32(100), batch.ProgressPercent) // (10+3+2)/15 * 100 = 100% +} + +func TestSetTotalDocuments_ThenUpdateProgress(t *testing.T) { + cfg := &TestConfig{} + test.CreateDB(t, cfg) + + service := documentbatch.New(cfg) + ctx := t.Context() + + // Create test client + clientID := "test_client_set_total_flow" + err := cfg.GetDBQueries().CreateClient(ctx, &repository.CreateClientParams{ + Clientid: clientID, + Name: "Test Client Set Total Flow", + }) + require.NoError(t, err) + + // Create batch with totalDocs=0 + batchID, err := service.Create(ctx, clientID, "flow.zip", 0) + require.NoError(t, err) + + // Set total to 20 + err = service.SetTotalDocuments(ctx, batchID, 20) + require.NoError(t, err) + + // Update progress (10 processed, 5 failed, 3 invalid) + err = service.UpdateProgress(ctx, clientID, batchID, 10, 5, 3) + require.NoError(t, err) + + // Assert ProgressPercent == 90 (18/20 * 100) + batch, err := cfg.GetDBQueries().GetBatchUpload(ctx, &repository.GetBatchUploadParams{ + ID: batchID, + ClientID: clientID, + }) + require.NoError(t, err) + assert.Equal(t, int32(90), batch.ProgressPercent) +} + // TestCheckDuplicate creates a document, then verifies that CheckDuplicate // returns its ID when the hash matches. func TestCheckDuplicate(t *testing.T) { @@ -751,3 +833,141 @@ func TestCheckDuplicate(t *testing.T) { require.NoError(t, err) assert.Nil(t, noMatch) } + +// TestGet_DerivesSummaryCountsFromOutcomes verifies that the Get endpoint +// derives ProcessedDocuments, FailedDocuments, and InvalidTypeDocuments from +// actual document outcome states rather than the extraction-phase counters +// stored in batch_uploads. +func TestGet_DerivesSummaryCountsFromOutcomes(t *testing.T) { + cfg := &TestConfig{} + test.CreateDB(t, cfg) + ctx := t.Context() + + service := documentbatch.New(cfg) + + clientID := "test_derive_counts_" + uuid.New().String()[:8] + err := cfg.GetDBQueries().CreateClient(ctx, &repository.CreateClientParams{ + Clientid: clientID, + Name: "Test Client Derive Counts", + }) + require.NoError(t, err) + + // Create batch -- extraction-phase counters will all be zero + batchID, err := service.Create(ctx, clientID, "mixed.zip", 0) + require.NoError(t, err) + + // Set total so progress percent can be calculated + err = service.SetTotalDocuments(ctx, batchID, 7) + require.NoError(t, err) + + // Create real documents for outcomes that require document_id + docA, err := cfg.GetDBQueries().CreateDocument(ctx, &repository.CreateDocumentParams{ + Clientid: clientID, Hash: "hash_a", BatchID: &batchID, + }) + require.NoError(t, err) + docB, err := cfg.GetDBQueries().CreateDocument(ctx, &repository.CreateDocumentParams{ + Clientid: clientID, Hash: "hash_b", BatchID: &batchID, + }) + require.NoError(t, err) + docC, err := cfg.GetDBQueries().CreateDocument(ctx, &repository.CreateDocumentParams{ + Clientid: clientID, Hash: "hash_c", BatchID: &batchID, + }) + require.NoError(t, err) + + // Record outcomes: 3 processed, 3 failed, 1 invalid_type + err = service.RecordOutcome(ctx, batchID, "a.pdf", + repository.BatchOutcomeStatusCleanPassed, nil, &docA) + require.NoError(t, err) + + err = service.RecordOutcome(ctx, batchID, "b.pdf", + repository.BatchOutcomeStatusDuplicate, nil, &docB) + require.NoError(t, err) + + err = service.RecordOutcome(ctx, batchID, "c.pdf", + repository.BatchOutcomeStatusInitDuplicate, nil, &docC) + require.NoError(t, err) + + err = service.RecordOutcome(ctx, batchID, "d.pdf", + repository.BatchOutcomeStatusCleanFailed, nil, nil) + require.NoError(t, err) + + errOpen := "cannot open" + err = service.RecordOutcome(ctx, batchID, "e.pdf", + repository.BatchOutcomeStatusFailedOpen, &errOpen, nil) + require.NoError(t, err) + + errRead := "truncated" + err = service.RecordOutcome(ctx, batchID, "f.pdf", + repository.BatchOutcomeStatusFailedRead, &errRead, nil) + require.NoError(t, err) + + err = service.RecordOutcome(ctx, batchID, "g.exe", + repository.BatchOutcomeStatusInvalidType, nil, nil) + require.NoError(t, err) + + // Call Get and assert derived summary counts + details, err := service.Get(ctx, clientID, batchID) + require.NoError(t, err) + + assert.Equal(t, int32(3), details.ProcessedDocuments, + "processed should count clean_passed + duplicate + init_duplicate") + assert.Equal(t, int32(3), details.FailedDocuments, + "failed should count clean_failed + failed_open + failed_read") + assert.Equal(t, int32(1), details.InvalidTypeDocuments, + "invalid_type should count invalid_type outcomes") + assert.Equal(t, int32(100), details.ProgressPercent, + "progress should be 100%% when all 7 outcomes are terminal") + assert.Equal(t, int32(7), details.TotalDocuments) +} + +// TestGet_DerivedCountsWithInProgressOutcomes verifies that non-terminal +// outcomes (submitted, init_complete, sync_complete) are not counted in +// any summary bucket. +func TestGet_DerivedCountsWithInProgressOutcomes(t *testing.T) { + cfg := &TestConfig{} + test.CreateDB(t, cfg) + ctx := t.Context() + + service := documentbatch.New(cfg) + + clientID := "test_inprog_counts_" + uuid.New().String()[:8] + err := cfg.GetDBQueries().CreateClient(ctx, &repository.CreateClientParams{ + Clientid: clientID, + Name: "Test Client InProgress Counts", + }) + require.NoError(t, err) + + batchID, err := service.Create(ctx, clientID, "partial.zip", 0) + require.NoError(t, err) + err = service.SetTotalDocuments(ctx, batchID, 3) + require.NoError(t, err) + + // 1 terminal, 2 non-terminal + docA, err := cfg.GetDBQueries().CreateDocument(ctx, &repository.CreateDocumentParams{ + Clientid: clientID, Hash: "hash_term", BatchID: &batchID, + }) + require.NoError(t, err) + + err = service.RecordOutcome(ctx, batchID, "a.pdf", + repository.BatchOutcomeStatusCleanPassed, nil, &docA) + require.NoError(t, err) + + err = service.RecordOutcome(ctx, batchID, "b.pdf", + repository.BatchOutcomeStatusSubmitted, nil, nil) + require.NoError(t, err) + + err = service.RecordOutcome(ctx, batchID, "c.pdf", + repository.BatchOutcomeStatusInitComplete, nil, nil) + require.NoError(t, err) + + details, err := service.Get(ctx, clientID, batchID) + require.NoError(t, err) + + assert.Equal(t, int32(1), details.ProcessedDocuments, + "only terminal processed outcomes should be counted") + assert.Equal(t, int32(0), details.FailedDocuments, + "no failed outcomes recorded") + assert.Equal(t, int32(0), details.InvalidTypeDocuments) + assert.Equal(t, int32(33), details.ProgressPercent, + "only 1 of 3 outcomes is terminal: 33%%") +} diff --git a/internal/document/clean/clean.go b/internal/document/clean/clean.go index 735adf57..8861e8b4 100644 --- a/internal/document/clean/clean.go +++ b/internal/document/clean/clean.go @@ -5,6 +5,8 @@ import ( "database/sql" "errors" "log/slog" + "path" + "strings" "queryorchestration/internal/database/repository" documenttypes "queryorchestration/internal/document/types" @@ -46,9 +48,15 @@ func (s *Service) executeCleanTasks(ctx context.Context, params *CleanParams) (* length = *out.ContentLength } - mimeType, err := s.getAcceptedMimeType(ctx, params, out.ContentType, length) + extension := strings.ToLower(path.Ext(params.Key.String())) + mimeType, err := s.getAcceptedMimeType(ctx, params, out.ContentType, length, extension) if err != nil { return nil, err + } else if mimeType == documenttypes.MimeTypeOLE2Encrypted { + reason := documenttypes.InvalidDocumentPasswordProtected + return &ExecuteCleanResponse{ + failReason: &reason, + }, nil } else if mimeType == documenttypes.MimeTypeInvalid { reason := documenttypes.InvalidDocumentMimeType return &ExecuteCleanResponse{ diff --git a/internal/document/clean/contentType.go b/internal/document/clean/contentType.go index 10cdb095..112e6ca2 100644 --- a/internal/document/clean/contentType.go +++ b/internal/document/clean/contentType.go @@ -1,9 +1,13 @@ package documentclean import ( + "archive/zip" "bytes" "context" "fmt" + "io" + "regexp" + "strings" documenttypes "queryorchestration/internal/document/types" @@ -12,29 +16,49 @@ import ( var AcceptMimeTypes = []documenttypes.MimeType{ documenttypes.MimeTypePDF, + documenttypes.MimeTypeTIFF, + documenttypes.MimeTypeJPEG, + documenttypes.MimeTypePNG, + documenttypes.MimeTypeBMP, + documenttypes.MimeTypeDOCX, + documenttypes.MimeTypeXLSX, + documenttypes.MimeTypePPTX, + documenttypes.MimeTypeTXT, + documenttypes.MimeTypeEML, } -const ( - PDFSignatureStr = "%PDF-" -) - -const ( - PDFSignatureEndStr = "%%EOF" -) - +// Magic byte signatures ordered from most-specific to least-specific. var ( - PDFSignature = []byte(PDFSignatureStr) + sigPNG = []byte{0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A} // 8 bytes + sigOLE2 = []byte{0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1} // 8 bytes + sigPDF = []byte(PDFSignatureStr) // 5 bytes prefix + sigTIFF_LE = []byte{0x49, 0x49, 0x2A, 0x00} // 4 bytes little-endian + sigTIFF_BE = []byte{0x4D, 0x4D, 0x00, 0x2A} // 4 bytes big-endian + sigZIP = []byte{0x50, 0x4B, 0x03, 0x04} // 4 bytes + sigJPEG = []byte{0xFF, 0xD8, 0xFF} // 3 bytes + sigBMP = []byte{0x42, 0x4D} // 2 bytes +) + +const ( + PDFSignatureStr = "%PDF-" + PDFSignatureEndStr = "%%EOF" ) var ( PDFSignatureEnd = []byte(PDFSignatureEndStr) ) +// emlHeaderPattern matches RFC 822 header fields (e.g., "From:", "Subject:"). +var emlHeaderPattern = regexp.MustCompile(`(?m)^[A-Za-z][A-Za-z0-9-]*:`) + +// emlRequiredHeaders are the headers that confirm a file is an email message. +var emlRequiredHeaders = []string{"From:", "To:", "Subject:", "Date:"} + // getAcceptedMimeType determines the file's MIME type by inspecting actual content. // S3 ContentType metadata is derived from the file extension and cannot be trusted, // so content-based validation (magic bytes) always runs first. -func (s *Service) getAcceptedMimeType(ctx context.Context, params *CleanParams, contentType *string, length int64) (documenttypes.MimeType, error) { - bodyMimeType, err := s.getBodyMimeType(ctx, params, length) +func (s *Service) getAcceptedMimeType(ctx context.Context, params *CleanParams, contentType *string, length int64, extension string) (documenttypes.MimeType, error) { + bodyMimeType, err := s.getBodyMimeType(ctx, params, length, extension) if err != nil { return documenttypes.MimeTypeInvalid, err } @@ -70,23 +94,179 @@ func (s *Service) getMetadataMimeType(contentType *string) documenttypes.MimeTyp return documenttypes.MimeTypeInvalid } -func (s *Service) getBodyMimeType(ctx context.Context, params *CleanParams, length int64) (documenttypes.MimeType, error) { - startBuffer, err := s.getBytesBuffer(ctx, params, 0, 5) - if err != nil { - return documenttypes.MimeTypeInvalid, err - } - endBuffer, err := s.getBytesBuffer(ctx, params, length-6, length) +// getBodyMimeType determines MIME type from file content magic bytes. +// Detection order is most-specific to least-specific signature length: +// PNG(8) -> OLE2(8) -> PDF(5+5) -> TIFF(4) -> ZIP/Office(4) -> JPEG(3) -> BMP(2) -> EML(text) -> TXT(fallback) +func (s *Service) getBodyMimeType(ctx context.Context, params *CleanParams, length int64, extension string) (documenttypes.MimeType, error) { + // Read first 8 bytes for binary signature detection + startBuffer, err := s.getBytesBuffer(ctx, params, 0, 8) if err != nil { return documenttypes.MimeTypeInvalid, err } - prefixMimeType := documenttypes.MimeTypeInvalid - - if bytes.HasPrefix(startBuffer, PDFSignature) && bytes.HasSuffix(endBuffer, PDFSignatureEnd) { - prefixMimeType = documenttypes.MimeTypePDF + // 1. PNG (8 bytes -- most specific) + if bytes.HasPrefix(startBuffer, sigPNG) { + return documenttypes.MimeTypePNG, nil } - return prefixMimeType, nil + // 2. OLE2 (8 bytes) -- encrypted Office documents use OLE2 wrapper + if bytes.HasPrefix(startBuffer, sigOLE2) { + // Fetch full file to probe for EncryptedPackage stream. + fullBuf, fullErr := s.getBytesBuffer(ctx, params, 0, length) + if fullErr != nil { + return documenttypes.MimeTypeInvalid, fullErr + } + if documenttypes.IsOLE2Encrypted(fullBuf) { + return documenttypes.MimeTypeOLE2Encrypted, nil + } + return documenttypes.MimeTypeInvalid, nil + } + + // 3. PDF (5-byte prefix + suffix, with tolerance for trailing whitespace) + if bytes.HasPrefix(startBuffer, sigPDF) { + endBuffer, err := s.getBytesBuffer(ctx, params, length-16, length) + if err != nil { + return documenttypes.MimeTypeInvalid, err + } + endBuffer = bytes.TrimRight(endBuffer, " \t\r\n") + if bytes.HasSuffix(endBuffer, PDFSignatureEnd) { + return documenttypes.MimeTypePDF, nil + } + } + + // 4. TIFF (4 bytes -- little-endian or big-endian) + if bytes.HasPrefix(startBuffer, sigTIFF_LE) || bytes.HasPrefix(startBuffer, sigTIFF_BE) { + return documenttypes.MimeTypeTIFF, nil + } + + // 5. ZIP / Office (4 bytes) -- disambiguate DOCX/XLSX/PPTX by Content_Types.xml + if bytes.HasPrefix(startBuffer, sigZIP) { + return s.detectOfficeType(ctx, params, length) + } + + // 6. JPEG (3 bytes) + if bytes.HasPrefix(startBuffer, sigJPEG) { + return documenttypes.MimeTypeJPEG, nil + } + + // 7. BMP (2 bytes) + if bytes.HasPrefix(startBuffer, sigBMP) { + return documenttypes.MimeTypeBMP, nil + } + + // 8. EML -- text-based, check for RFC 822 headers + if s.looksLikeEML(ctx, params, length) { + return documenttypes.MimeTypeEML, nil + } + + // 9. TXT -- fallback, only if extension is .txt and content passes text checks + if extension == ".txt" { + if s.looksLikeTXT(startBuffer) { + return documenttypes.MimeTypeTXT, nil + } + } + + return documenttypes.MimeTypeInvalid, nil +} + +// detectOfficeType reads the full ZIP file, decompresses [Content_Types].xml, +// and inspects it to distinguish between DOCX, XLSX, and PPTX. +func (s *Service) detectOfficeType(ctx context.Context, params *CleanParams, length int64) (documenttypes.MimeType, error) { + // Fetch the full file so the ZIP central directory (at end of file) is available. + buf, err := s.getBytesBuffer(ctx, params, 0, length) + if err != nil { + return documenttypes.MimeTypeInvalid, err + } + + zr, err := zip.NewReader(bytes.NewReader(buf), int64(len(buf))) + if err != nil { + return documenttypes.MimeTypeInvalid, nil + } + + // Find and decompress [Content_Types].xml. + for _, f := range zr.File { + if f.Name != "[Content_Types].xml" { + continue + } + rc, openErr := f.Open() + if openErr != nil { + return documenttypes.MimeTypeInvalid, nil + } + ctData, readErr := io.ReadAll(rc) + rc.Close() + if readErr != nil { + return documenttypes.MimeTypeInvalid, nil + } + content := string(ctData) + if strings.Contains(content, "wordprocessingml.document.main+xml") { + return documenttypes.MimeTypeDOCX, nil + } + if strings.Contains(content, "spreadsheetml.sheet.main+xml") { + return documenttypes.MimeTypeXLSX, nil + } + if strings.Contains(content, "presentationml.presentation.main+xml") { + return documenttypes.MimeTypePPTX, nil + } + return documenttypes.MimeTypeInvalid, nil + } + + // ZIP file but no [Content_Types].xml -- not a recognized Office format + return documenttypes.MimeTypeInvalid, nil +} + +// looksLikeEML checks if the file starts with RFC 822 email headers. +func (s *Service) looksLikeEML(ctx context.Context, params *CleanParams, length int64) bool { + readLen := min(length, 8192) + buf, err := s.getBytesBuffer(ctx, params, 0, readLen) + if err != nil { + return false + } + + // Must have at least 3 header-like lines + matches := emlHeaderPattern.FindAll(buf, -1) + if len(matches) < 3 { + return false + } + + // Must have at least one of the required email headers + content := string(buf) + for _, h := range emlRequiredHeaders { + if bytes.Contains([]byte(content), []byte(h)) { + return true + } + } + + return false +} + +// looksLikeTXT verifies the first bytes don't match any known binary signature +// and contain no null bytes (which would indicate binary content). +// UTF-16 files with a BOM are allowed through -- the null bytes are expected encoding. +func (s *Service) looksLikeTXT(startBuffer []byte) bool { + // Reject if it matches any known binary signature + binarySignatures := [][]byte{sigPNG, sigOLE2, sigPDF, sigTIFF_LE, sigTIFF_BE, sigZIP, sigJPEG, sigBMP} + for _, sig := range binarySignatures { + if bytes.HasPrefix(startBuffer, sig) { + return false + } + } + + // UTF-16 files with BOM are valid text -- skip null-byte check for these. + if len(startBuffer) >= 2 { + if startBuffer[0] == 0xFF && startBuffer[1] == 0xFE { // UTF-16LE BOM + return true + } + if startBuffer[0] == 0xFE && startBuffer[1] == 0xFF { // UTF-16BE BOM + return true + } + } + + // Check for null bytes in the start buffer + if bytes.Contains(startBuffer, []byte{0x00}) { + return false + } + + return true } func (s *Service) getBytesBuffer(ctx context.Context, params *CleanParams, start int64, length int64) ([]byte, error) { @@ -111,9 +291,9 @@ func (s *Service) getBytesBuffer(ctx context.Context, params *CleanParams, start defer out.Body.Close() buffer := make([]byte, length) - n, err := out.Body.Read(buffer) - if err != nil && n == 0 { - return nil, fmt.Errorf("unable to read object body: %w", err) + n, err := io.ReadFull(out.Body, buffer) + if err != nil && err != io.ErrUnexpectedEOF { + return nil, fmt.Errorf("reading S3 object body: %w", err) } return buffer[:n], nil diff --git a/internal/document/clean/service_test.go b/internal/document/clean/service_test.go index f931fa91..13752666 100644 --- a/internal/document/clean/service_test.go +++ b/internal/document/clean/service_test.go @@ -213,3 +213,214 @@ func TestClean_RejectsNonPDFWithPDFContentType(t *testing.T) { }) } } + +// TestClean_AcceptsPDFWithTrailingNewline verifies that valid PDF files are +// accepted even when trailing whitespace (newlines) follows the %%EOF marker. +// Many PDF generators append a trailing newline; the cleaner must tolerate it. +func TestClean_AcceptsPDFWithTrailingNewline(t *testing.T) { + cfg := &DocCleanConfig{} + test.CreateDB(t, cfg) + test.CreateAWSResources(t, cfg) + ctx := t.Context() + + svc := documentclean.New(cfg) + + uniqueSuffix := uuid.New().String()[:8] + clientID := "pdf_trailing_nl_" + uniqueSuffix + err := cfg.GetDBQueries().CreateClient(ctx, &repository.CreateClientParams{ + Clientid: clientID, + Name: "Test PDF Trailing Newline " + uniqueSuffix, + }) + require.NoError(t, err) + + // Structurally valid minimal PDF (cross-reference table, catalog, page). + // The base ends with %%EOF and no trailing newline; each sub-test appends its own suffix. + pdfBase := []byte("%PDF-1.4\n1 0 obj\n<>\nendobj\n" + + "2 0 obj\n<>\nendobj\n" + + "3 0 obj\n<>\nendobj\n" + + "xref\n0 4\n0000000000 65535 f \n0000000009 00000 n \n0000000058 00000 n \n0000000115 00000 n \n" + + "trailer\n<>\nstartxref\n190\n%%EOF") + + tests := []struct { + name string + suffix string + }{ + {name: "%%EOF\\n (Unix)", suffix: "\n"}, + {name: "%%EOF\\r\\n (Windows)", suffix: "\r\n"}, + {name: "%%EOF (no newline)", suffix: ""}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + content := append([]byte{}, pdfBase...) + content = append(content, []byte(tt.suffix)...) + + location := objectstore.BucketKey{ + Location: objectstore.Import, + ClientID: clientID, + CreatedAt: time.Now().UTC(), + EntityID: uuid.New(), + } + + _, err := cfg.GetStoreClient().PutObject(ctx, &s3.PutObjectInput{ + Bucket: aws.String(cfg.GetBucket()), + Key: aws.String(location.String()), + Body: bytes.NewReader(content), + ContentType: aws.String("application/pdf"), + }) + require.NoError(t, err) + + headResp, err := cfg.GetStoreClient().HeadObject(ctx, &s3.HeadObjectInput{ + Bucket: aws.String(cfg.GetBucket()), + Key: aws.String(location.String()), + }) + require.NoError(t, err) + etag := *headResp.ETag + + docID, err := cfg.GetDBQueries().CreateDocument(ctx, &repository.CreateDocumentParams{ + Clientid: clientID, + Hash: etag, + }) + require.NoError(t, err) + + err = cfg.GetDBQueries().AddDocumentEntry(ctx, &repository.AddDocumentEntryParams{ + Documentid: docID, + Bucket: cfg.GetBucket(), + Key: location.String(), + }) + require.NoError(t, err) + + result, err := svc.Clean(ctx, docID) + require.NoError(t, err) + require.NotNil(t, result) + assert.True(t, result.Passed, "valid PDF with trailing whitespace %q after %%%%EOF should be accepted", tt.suffix) + }) + } +} + +// TestClean_AcceptsTXTWithExtension verifies that a valid UTF-8 text file +// is accepted when the S3 key includes a .txt file extension. +func TestClean_AcceptsTXTWithExtension(t *testing.T) { + cfg := &DocCleanConfig{} + test.CreateDB(t, cfg) + test.CreateAWSResources(t, cfg) + ctx := t.Context() + + svc := documentclean.New(cfg) + + uniqueSuffix := uuid.New().String()[:8] + clientID := "txt_ext_" + uniqueSuffix + err := cfg.GetDBQueries().CreateClient(ctx, &repository.CreateClientParams{ + Clientid: clientID, + Name: "Test TXT Extension " + uniqueSuffix, + }) + require.NoError(t, err) + + txtContent := []byte("Hello, this is a plain text file.\nIt has multiple lines.\nNo binary content here.") + + fileType := "txt" + location := objectstore.BucketKey{ + Location: objectstore.Import, + ClientID: clientID, + CreatedAt: time.Now().UTC(), + EntityID: uuid.New(), + FileType: &fileType, + } + + _, err = cfg.GetStoreClient().PutObject(ctx, &s3.PutObjectInput{ + Bucket: aws.String(cfg.GetBucket()), + Key: aws.String(location.String()), + Body: bytes.NewReader(txtContent), + ContentType: aws.String("text/plain"), + }) + require.NoError(t, err) + + headResp, err := cfg.GetStoreClient().HeadObject(ctx, &s3.HeadObjectInput{ + Bucket: aws.String(cfg.GetBucket()), + Key: aws.String(location.String()), + }) + require.NoError(t, err) + etag := *headResp.ETag + + docID, err := cfg.GetDBQueries().CreateDocument(ctx, &repository.CreateDocumentParams{ + Clientid: clientID, + Hash: etag, + }) + require.NoError(t, err) + + err = cfg.GetDBQueries().AddDocumentEntry(ctx, &repository.AddDocumentEntryParams{ + Documentid: docID, + Bucket: cfg.GetBucket(), + Key: location.String(), + }) + require.NoError(t, err) + + result, err := svc.Clean(ctx, docID) + require.NoError(t, err) + require.NotNil(t, result) + assert.True(t, result.Passed, "valid TXT file with .txt extension should be accepted") +} + +// TestClean_RejectsTXTWithoutExtension verifies that a text file without +// a .txt extension on the S3 key is rejected (regression guard for old uploads). +func TestClean_RejectsTXTWithoutExtension(t *testing.T) { + cfg := &DocCleanConfig{} + test.CreateDB(t, cfg) + test.CreateAWSResources(t, cfg) + ctx := t.Context() + + svc := documentclean.New(cfg) + + uniqueSuffix := uuid.New().String()[:8] + clientID := "txt_noext_" + uniqueSuffix + err := cfg.GetDBQueries().CreateClient(ctx, &repository.CreateClientParams{ + Clientid: clientID, + Name: "Test TXT No Extension " + uniqueSuffix, + }) + require.NoError(t, err) + + txtContent := []byte("Hello, this is a plain text file.\nIt has multiple lines.\nNo binary content here.") + + // No FileType set -- simulates old uploads without extension + location := objectstore.BucketKey{ + Location: objectstore.Import, + ClientID: clientID, + CreatedAt: time.Now().UTC(), + EntityID: uuid.New(), + } + + _, err = cfg.GetStoreClient().PutObject(ctx, &s3.PutObjectInput{ + Bucket: aws.String(cfg.GetBucket()), + Key: aws.String(location.String()), + Body: bytes.NewReader(txtContent), + ContentType: aws.String("text/plain"), + }) + require.NoError(t, err) + + headResp, err := cfg.GetStoreClient().HeadObject(ctx, &s3.HeadObjectInput{ + Bucket: aws.String(cfg.GetBucket()), + Key: aws.String(location.String()), + }) + require.NoError(t, err) + etag := *headResp.ETag + + docID, err := cfg.GetDBQueries().CreateDocument(ctx, &repository.CreateDocumentParams{ + Clientid: clientID, + Hash: etag, + }) + require.NoError(t, err) + + err = cfg.GetDBQueries().AddDocumentEntry(ctx, &repository.AddDocumentEntryParams{ + Documentid: docID, + Bucket: cfg.GetBucket(), + Key: location.String(), + }) + require.NoError(t, err) + + result, err := svc.Clean(ctx, docID) + require.NoError(t, err) + require.NotNil(t, result) + assert.False(t, result.Passed, "TXT file without .txt extension should be rejected") + require.NotNil(t, result.FailReason) + assert.Equal(t, "invalid_mimetype", *result.FailReason) +} diff --git a/internal/document/types/bmp.go b/internal/document/types/bmp.go new file mode 100644 index 00000000..c09fcdfa --- /dev/null +++ b/internal/document/types/bmp.go @@ -0,0 +1,82 @@ +package documenttypes + +import ( + "bytes" + "context" + "fmt" + "io" + + "golang.org/x/image/bmp" +) + +// BMP implements the File interface for BMP image validation. +// It validates magic bytes, dimensions, and content. +// BMP DPI metadata is not checked as it is unreliable. +type BMP struct { + data []byte +} + +// NewBMPFromReader creates a new BMP validator by reading all bytes from r. +func NewBMPFromReader(r io.Reader) (*BMP, error) { + data, err := io.ReadAll(r) + if err != nil { + return nil, err + } + return NewBMP(data), nil +} + +// NewBMP creates a new BMP validator from raw file bytes. +func NewBMP(data []byte) *BMP { + return &BMP{data: data} +} + +// IsCorrupt validates the BMP file for corruption or unsupported content. +func (s *BMP) IsCorrupt(_ context.Context) *InvalidDocumentReason { + if reason := s.checkMagicBytes(); reason != nil { + return reason + } + + img, err := bmp.Decode(bytes.NewReader(s.data)) + if err != nil { + return invalidReason(InvalidDocumentRead) + } + + if len(s.data) > imageMaxFileSize { + return invalidReason(InvalidDocumentLargeFile) + } + + bounds := img.Bounds() + if reason := checkImageDimensions(bounds.Dx(), bounds.Dy()); reason != nil { + return reason + } + + if isSolidColor(img) { + return invalidReason(InvalidDocumentEmptyContent) + } + + return nil +} + +// GetPageCount returns 1 since BMP files are always single-page. +func (s *BMP) GetPageCount(_ context.Context) (int, error) { + return 1, nil +} + +// GetPage returns the raw BMP data for page index 0. +func (s *BMP) GetPage(_ context.Context, index int) ([]byte, error) { + if index != 0 { + return nil, fmt.Errorf("bmp: invalid page index %d: BMP files have exactly 1 page", index) + } + return s.data, nil +} + +// checkMagicBytes verifies the BMP file signature: 42 4D ("BM"). +func (s *BMP) checkMagicBytes() *InvalidDocumentReason { + if len(s.data) < 2 { + return invalidReason(InvalidDocumentMimeType) + } + if s.data[0] != 0x42 || s.data[1] != 0x4D { + return invalidReason(InvalidDocumentMimeType) + } + return nil +} diff --git a/internal/document/types/bmp_test.go b/internal/document/types/bmp_test.go new file mode 100644 index 00000000..dcdeddd4 --- /dev/null +++ b/internal/document/types/bmp_test.go @@ -0,0 +1,50 @@ +package documenttypes + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestBMP_ValidFile(t *testing.T) { + data, err := os.ReadFile("testdata/multiformat/valid.bmp") + require.NoError(t, err) + + b := NewBMP(data) + ctx := t.Context() + + t.Run("IsCorrupt returns nil", func(t *testing.T) { + reason := b.IsCorrupt(ctx) + assert.Nil(t, reason) + }) + + t.Run("GetPageCount returns 1", func(t *testing.T) { + count, err := b.GetPageCount(ctx) + require.NoError(t, err) + assert.Equal(t, 1, count) + }) +} + +func TestBMP_InvalidMagicBytes(t *testing.T) { + data := []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05} + b := NewBMP(data) + + reason := b.IsCorrupt(t.Context()) + require.NotNil(t, reason) + assert.Equal(t, InvalidDocumentMimeType, *reason) +} + +func TestBMP_CorruptData(t *testing.T) { + // Valid BMP magic bytes ("BM") followed by garbage data. + data := make([]byte, 128) + data[0] = 0x42 // 'B' + data[1] = 0x4D // 'M' + // Remaining bytes are zeros -- not a valid BMP file. + + b := NewBMP(data) + reason := b.IsCorrupt(t.Context()) + require.NotNil(t, reason) + assert.Equal(t, InvalidDocumentRead, *reason) +} diff --git a/internal/document/types/contentType.go b/internal/document/types/contentType.go index 60fbc230..b4ddb69c 100644 --- a/internal/document/types/contentType.go +++ b/internal/document/types/contentType.go @@ -1,8 +1,10 @@ package documenttypes import ( + "bytes" "context" "fmt" + "io" "queryorchestration/internal/serviceconfig/objectstore" @@ -13,7 +15,17 @@ type MimeType string const ( MimeTypePDF MimeType = "application/pdf" + MimeTypeTIFF MimeType = "image/tiff" + MimeTypeJPEG MimeType = "image/jpeg" + MimeTypePNG MimeType = "image/png" + MimeTypeBMP MimeType = "image/bmp" + MimeTypeDOCX MimeType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document" + MimeTypeXLSX MimeType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" + MimeTypePPTX MimeType = "application/vnd.openxmlformats-officedocument.presentationml.presentation" + MimeTypeTXT MimeType = "text/plain" + MimeTypeEML MimeType = "message/rfc822" MimeTypeBinaryOctetStream MimeType = "binary/octet-stream" + MimeTypeOLE2Encrypted MimeType = "ole2_encrypted" MimeTypeInvalid MimeType = "invalid" ) @@ -41,14 +53,37 @@ func GetFile(ctx context.Context, cfg objectstore.ConfigProvider, params GetFile } defer resp.Body.Close() + data, err := io.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("failed to read file data: %w", err) + } + var file File switch params.Mimetype { case MimeTypePDF: - pdf, err := NewPDFFromReader(resp.Body) + pdf, err := NewPDFFromReader(bytes.NewReader(data)) if err != nil { return nil, err } file = pdf + case MimeTypeTIFF: + file = NewTIFF(data) + case MimeTypeJPEG: + file = NewJPEG(data) + case MimeTypePNG: + file = NewPNG(data) + case MimeTypeBMP: + file = NewBMP(data) + case MimeTypeDOCX: + file = NewDOCX(data) + case MimeTypeXLSX: + file = NewXLSX(data) + case MimeTypePPTX: + file = NewPPTX(data) + case MimeTypeTXT: + file = NewTXT(data) + case MimeTypeEML: + file = NewEML(data) default: return nil, fmt.Errorf("invalid mimetype: %s", params.Mimetype) } diff --git a/internal/document/types/docx.go b/internal/document/types/docx.go new file mode 100644 index 00000000..76afd91f --- /dev/null +++ b/internal/document/types/docx.go @@ -0,0 +1,227 @@ +package documenttypes + +import ( + "archive/zip" + "context" + "encoding/xml" + "strings" +) + +// DOCX represents a Word OOXML document for validation and page extraction. +type DOCX struct { + data []byte +} + +// NewDOCX creates a new DOCX validator from raw file data. +func NewDOCX(data []byte) *DOCX { + return &DOCX{data: data} +} + +// docxBody is a minimal XML representation of the word/document.xml body, +// capturing text runs, drawings, pictures, and section breaks. +type docxBody struct { + XMLName xml.Name `xml:"document"` + Body docxBodyInner `xml:"body"` +} + +type docxBodyInner struct { + Paragraphs []docxParagraph `xml:"p"` + SectPr *struct{} `xml:"sectPr"` +} + +type docxParagraph struct { + Runs []docxRun `xml:"r"` + Drawings []struct{} `xml:"drawing"` + Pictures []struct{} `xml:"pict"` + SectPr *struct{} `xml:"pPr>sectPr"` +} + +type docxRun struct { + Text []string `xml:"t"` + Drawings []struct{} `xml:"drawing"` + Pictures []struct{} `xml:"pict"` +} + +// docxSettings is a minimal representation of word/settings.xml for +// detecting document protection with encryption attributes. +type docxSettings struct { + XMLName xml.Name `xml:"settings"` + DocumentProtection *docxDocProtection `xml:"documentProtection"` +} + +type docxDocProtection struct { + CryptAlgorithmSid string `xml:"cryptAlgorithmSid,attr"` + CryptSpinCount string `xml:"cryptSpinCount,attr"` + Hash string `xml:"hash,attr"` +} + +// IsCorrupt validates the DOCX document, returning the reason it is invalid +// or nil if the document passes all checks. +func (s *DOCX) IsCorrupt(_ context.Context) *InvalidDocumentReason { + // 1. Check for OLE2 encryption (encrypted OOXML files use OLE2 wrapper) + if IsOLE2Encrypted(s.data) { + reason := InvalidDocumentPasswordProtected + return &reason + } + + // 2. Check ZIP signature + if !hasZIPSignature(s.data) { + reason := InvalidDocumentMimeType + return &reason + } + + // 3. Open ZIP and verify content type + zr, err := openOfficeZIP(s.data) + if err != nil { + reason := InvalidDocumentMimeType + return &reason + } + + ct, err := readZIPFile(zr, "[Content_Types].xml") + if err != nil || !strings.Contains(string(ct), "wordprocessingml.document.main+xml") { + reason := InvalidDocumentMimeType + return &reason + } + + // 4. Reject if macros are present + if hasVBAMacros(zr) { + reason := InvalidDocumentContainsMacros + return &reason + } + if r := s.hasEncryptionProtection(zr); r != nil { + return r + } + + // 5. Verify word/document.xml exists and parses + docXML, err := readZIPFile(zr, "word/document.xml") + if err != nil { + reason := InvalidDocumentRead + return &reason + } + var doc docxBody + if xmlErr := xml.Unmarshal(docXML, &doc); xmlErr != nil { + reason := InvalidDocumentRead + return &reason + } + + // 6. File size check + if len(s.data) > officeMaxFileSize { + reason := InvalidDocumentLargeFile + return &reason + } + + // 7. Content check: text, drawings, or pictures + if !s.hasContent(&doc) { + reason := InvalidDocumentEmptyContent + return &reason + } + + // 8. Page count check + pageCount := s.countPages(&doc) + if pageCount < 1 { + reason := InvalidDocumentZeroPageCount + return &reason + } + + return nil +} + +// GetPageCount estimates the number of pages by counting section breaks + 1. +// Returns at least 1 if the document has content. +func (s *DOCX) GetPageCount(_ context.Context) (int, error) { + zr, err := openOfficeZIP(s.data) + if err != nil { + return 0, err + } + + docXML, err := readZIPFile(zr, "word/document.xml") + if err != nil { + return 0, err + } + + var doc docxBody + if xmlErr := xml.Unmarshal(docXML, &doc); xmlErr != nil { + return 0, xmlErr + } + + count := max(s.countPages(&doc), 1) + return count, nil +} + +// GetPage returns the raw document bytes for the requested page index. +// For single-page docs, returns the full document bytes regardless of index. +func (s *DOCX) GetPage(_ context.Context, _ int) ([]byte, error) { + return s.data, nil +} + +// hasEncryptionProtection checks word/settings.xml for documentProtection +// elements with encryption attributes. +func (s *DOCX) hasEncryptionProtection(zr *zip.Reader) *InvalidDocumentReason { + settingsXML, err := readZIPFile(zr, "word/settings.xml") + if err != nil { + // No settings file is not an error -- just no protection + return nil + } + + var settings docxSettings + if xmlErr := xml.Unmarshal(settingsXML, &settings); xmlErr != nil { + return nil + } + + if settings.DocumentProtection != nil && + (settings.DocumentProtection.CryptAlgorithmSid != "" || + settings.DocumentProtection.Hash != "") { + reason := InvalidDocumentPasswordProtected + return &reason + } + + return nil +} + +// hasContent checks whether the document contains any text, drawings, or pictures. +func (s *DOCX) hasContent(doc *docxBody) bool { + for _, p := range doc.Body.Paragraphs { + if len(p.Drawings) > 0 || len(p.Pictures) > 0 { + return true + } + for _, r := range p.Runs { + if len(r.Drawings) > 0 || len(r.Pictures) > 0 { + return true + } + for _, t := range r.Text { + if strings.TrimSpace(t) != "" { + return true + } + } + } + } + return false +} + +// countPages estimates page count from section breaks. +// Each in a paragraph's properties represents a section break. +// The final section is represented by the body-level sectPr. +func (s *DOCX) countPages(doc *docxBody) int { + count := 0 + for _, p := range doc.Body.Paragraphs { + if p.SectPr != nil { + count++ + } + } + // The body-level sectPr represents the last section + if doc.Body.SectPr != nil { + count++ + } + // Minimum 1 if there are paragraphs at all + if count == 0 && len(doc.Body.Paragraphs) > 0 { + count = 1 + } + return count +} + +// hasZIPSignature checks if data starts with the ZIP local file header signature. +func hasZIPSignature(data []byte) bool { + return len(data) >= 4 && + data[0] == 0x50 && data[1] == 0x4B && + data[2] == 0x03 && data[3] == 0x04 +} diff --git a/internal/document/types/docx_test.go b/internal/document/types/docx_test.go new file mode 100644 index 00000000..184da7b4 --- /dev/null +++ b/internal/document/types/docx_test.go @@ -0,0 +1,145 @@ +package documenttypes + +import ( + "archive/zip" + "bytes" + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestDOCX_ValidFile(t *testing.T) { + ctx := t.Context() + data, err := os.ReadFile("testdata/multiformat/valid.docx") + require.NoError(t, err) + + docx := NewDOCX(data) + + t.Run("IsCorrupt returns nil", func(t *testing.T) { + reason := docx.IsCorrupt(ctx) + assert.Nil(t, reason, "valid.docx should not be corrupt") + }) + + t.Run("GetPageCount >= 1", func(t *testing.T) { + count, err := docx.GetPageCount(ctx) + require.NoError(t, err) + assert.GreaterOrEqual(t, count, 1) + }) + + t.Run("GetPage returns data", func(t *testing.T) { + page, err := docx.GetPage(ctx, 0) + require.NoError(t, err) + assert.NotEmpty(t, page) + }) +} + +func TestDOCX_InvalidMagicBytes(t *testing.T) { + ctx := t.Context() + data := []byte("this is definitely not a ZIP or DOCX file") + + docx := NewDOCX(data) + reason := docx.IsCorrupt(ctx) + + require.NotNil(t, reason) + assert.Equal(t, InvalidDocumentMimeType, *reason) +} + +func TestDOCX_NotDOCX(t *testing.T) { + // Create a valid ZIP that does not contain DOCX content types. + ctx := t.Context() + + var buf bytes.Buffer + zw := zip.NewWriter(&buf) + + // Write a [Content_Types].xml without the DOCX content type + w, err := zw.Create("[Content_Types].xml") + require.NoError(t, err) + _, err = w.Write([]byte(` + + +`)) + require.NoError(t, err) + + require.NoError(t, zw.Close()) + + docx := NewDOCX(buf.Bytes()) + reason := docx.IsCorrupt(ctx) + + require.NotNil(t, reason) + assert.Equal(t, InvalidDocumentMimeType, *reason) +} + +func TestDOCX_WithMacros(t *testing.T) { + // macro.docx should be rejected -- documents with macros are not accepted. + ctx := t.Context() + data, err := os.ReadFile("testdata/multiformat/macro.docx") + require.NoError(t, err) + + docx := NewDOCX(data) + reason := docx.IsCorrupt(ctx) + + require.NotNil(t, reason) + assert.Equal(t, InvalidDocumentContainsMacros, *reason) +} + +func TestDOCX_Encrypted(t *testing.T) { + // encrypted.docx has the OLE2 signature but is not a parseable OLE2 compound + // document (malformed fixture). IsOLE2Encrypted returns false, then the ZIP + // signature check fails, so it returns InvalidDocumentMimeType. + // A real encrypted OLE2 file would be caught by IsOLE2Encrypted and return + // InvalidDocumentPasswordProtected. + ctx := t.Context() + data, err := os.ReadFile("testdata/multiformat/encrypted.docx") + require.NoError(t, err) + + docx := NewDOCX(data) + reason := docx.IsCorrupt(ctx) + + require.NotNil(t, reason) + assert.Equal(t, InvalidDocumentMimeType, *reason, + "malformed OLE2 file should fail ZIP signature check") +} + +func TestDOCX_EmptyContent(t *testing.T) { + // Build a minimal DOCX with proper structure but no text content. + ctx := t.Context() + + var buf bytes.Buffer + zw := zip.NewWriter(&buf) + + // [Content_Types].xml -- must include wordprocessingml.document.main+xml + w, err := zw.Create("[Content_Types].xml") + require.NoError(t, err) + _, err = w.Write([]byte(` + + +`)) + require.NoError(t, err) + + // word/document.xml -- valid structure but no text, no drawings, no pictures + w, err = zw.Create("word/document.xml") + require.NoError(t, err) + _, err = w.Write([]byte(` + + + + + + + + + +`)) + require.NoError(t, err) + + require.NoError(t, zw.Close()) + + docx := NewDOCX(buf.Bytes()) + reason := docx.IsCorrupt(ctx) + + require.NotNil(t, reason) + assert.Equal(t, InvalidDocumentEmptyContent, *reason) +} diff --git a/internal/document/types/eml.go b/internal/document/types/eml.go new file mode 100644 index 00000000..620a8817 --- /dev/null +++ b/internal/document/types/eml.go @@ -0,0 +1,328 @@ +package documenttypes + +import ( + "bytes" + "context" + "fmt" + "io" + "mime" + "mime/multipart" + "net/mail" + "regexp" + "strings" +) + +const ( + // maxEMLFileSize is the maximum allowed file size for email files (100MB). + maxEMLFileSize = 100 * 1024 * 1024 + // emlHeaderScanSize is the number of bytes to scan for RFC 822 headers. + emlHeaderScanSize = 8192 +) + +// htmlTagPattern matches HTML tags for stripping to plain text. +var htmlTagPattern = regexp.MustCompile(`<[^>]*>`) + +// requiredEMLHeaders is the set of headers of which at least one must be present +// for the file to be considered a valid email message. +var requiredEMLHeaders = []string{"From", "To", "Subject", "Date"} + +// EML implements the File interface for RFC 822 email message validation. +// It validates headers, detects attachments (rejecting if found), and +// verifies text body content exists. +type EML struct { + data []byte +} + +// NewEML creates a new EML validator from raw file bytes. +func NewEML(data []byte) *EML { + return &EML{data: data} +} + +// IsCorrupt validates the email file for corruption or missing content. +// It checks RFC 822 headers, parses the message, rejects if attachments +// are present, validates file size, and ensures body content exists. +func (s *EML) IsCorrupt(_ context.Context) *InvalidDocumentReason { + if reason := s.validateHeaders(); reason != nil { + return reason + } + + msg, err := mail.ReadMessage(bytes.NewReader(s.data)) + if err != nil { + r := InvalidDocumentRead + return &r + } + + if reason := s.detectAttachments(msg); reason != nil { + return reason + } + + if len(s.data) > maxEMLFileSize { + r := InvalidDocumentLargeFile + return &r + } + + body, reason := s.extractBody() + if reason != nil { + return reason + } + + if strings.TrimSpace(body) == "" { + r := InvalidDocumentEmptyContent + return &r + } + + return nil +} + +// GetPageCount returns the number of pages. Email messages are always 1 page. +func (s *EML) GetPageCount(_ context.Context) (int, error) { + return 1, nil +} + +// GetPage returns the body text of the email. Only page index 0 is valid. +func (s *EML) GetPage(_ context.Context, index int) ([]byte, error) { + if index != 0 { + return nil, fmt.Errorf("invalid page index %d: EML files have exactly 1 page", index) + } + + body, reason := s.extractBody() + if reason != nil { + return nil, fmt.Errorf("failed to extract EML body: %s", *reason) + } + + return []byte(body), nil +} + +// validateHeaders checks that the file begins with valid RFC 822 headers. +// At least one of From, To, Subject, or Date must be present, and the header +// block must be followed by a blank line separator. +func (s *EML) validateHeaders() *InvalidDocumentReason { + scanLen := min(len(s.data), emlHeaderScanSize) + + headerBlock := string(s.data[:scanLen]) + + // Headers must be followed by a blank line (CRLF+CRLF or LF+LF). + blankLineIdx := strings.Index(headerBlock, "\r\n\r\n") + if blankLineIdx == -1 { + blankLineIdx = strings.Index(headerBlock, "\n\n") + } + if blankLineIdx == -1 { + r := InvalidDocumentMimeType + return &r + } + + headerSection := headerBlock[:blankLineIdx] + + // Check that at least one required header is present. + foundRequired := false + for _, required := range requiredEMLHeaders { + // Match header at start of line: "HeaderName:" (case-insensitive). + pattern := "(?m)^(?i)" + regexp.QuoteMeta(required) + `\s*:` + matched, _ := regexp.MatchString(pattern, headerSection) + if matched { + foundRequired = true + break + } + } + + if !foundRequired { + r := InvalidDocumentMimeType + return &r + } + + return nil +} + +// detectAttachments checks if the message contains any MIME attachments or +// non-text parts. If found, the document is rejected -- the uploader must +// remove attachments before resubmitting. +func (s *EML) detectAttachments(msg *mail.Message) *InvalidDocumentReason { + contentType := msg.Header.Get("Content-Type") + if contentType == "" { + // Simple message with no Content-Type -- treat as text/plain, no attachments. + return nil + } + + mediaType, params, err := mime.ParseMediaType(contentType) + if err != nil { + // If we cannot parse Content-Type, the message is likely simple text. + return nil + } + + if !strings.HasPrefix(mediaType, "multipart/") { + // Single-part message: only text/plain and text/html are acceptable body types. + // Non-text content types (e.g., application/pdf) indicate the message body is + // binary content that should be rejected as an attachment. + if !strings.HasPrefix(mediaType, "text/plain") && !strings.HasPrefix(mediaType, "text/html") { + r := InvalidDocumentContainsAttachments + return &r + } + return nil + } + + boundary := params["boundary"] + if boundary == "" { + r := InvalidDocumentRead + return &r + } + + body, err := io.ReadAll(msg.Body) + if err != nil { + r := InvalidDocumentRead + return &r + } + + mr := multipart.NewReader(bytes.NewReader(body), boundary) + + for { + part, partErr := mr.NextPart() + if partErr == io.EOF { + break + } + if partErr != nil { + r := InvalidDocumentRead + return &r + } + + if isAttachmentPart(part) { + r := InvalidDocumentContainsAttachments + return &r + } + } + + return nil +} + +// isAttachmentPart determines whether a MIME part is an attachment or non-text +// content that should cause rejection. +func isAttachmentPart(part *multipart.Part) bool { + disposition := part.Header.Get("Content-Disposition") + if strings.HasPrefix(disposition, "attachment") { + return true + } + + ct := part.Header.Get("Content-Type") + if ct == "" { + // Default to text/plain per RFC 2045 -- not an attachment. + return false + } + + mediaType, _, err := mime.ParseMediaType(ct) + if err != nil { + return false + } + + return mediaType != "text/plain" && mediaType != "text/html" +} + +// extractBody parses the current message data and extracts text content. +// For multipart messages, it concatenates text/plain and text/html parts. +// HTML content is converted to plain text by stripping tags. +func (s *EML) extractBody() (string, *InvalidDocumentReason) { + msg, err := mail.ReadMessage(bytes.NewReader(s.data)) + if err != nil { + r := InvalidDocumentRead + return "", &r + } + + contentType := msg.Header.Get("Content-Type") + if contentType == "" { + return s.readBodyAsText(msg) + } + + mediaType, params, err := mime.ParseMediaType(contentType) + if err != nil { + return s.readBodyAsText(msg) + } + + if !strings.HasPrefix(mediaType, "multipart/") { + body, readErr := io.ReadAll(msg.Body) + if readErr != nil { + r := InvalidDocumentRead + return "", &r + } + return s.textFromPart(mediaType, body), nil + } + + return s.extractMultipartBody(msg, params["boundary"]) +} + +// readBodyAsText reads the entire message body as plain text. +func (s *EML) readBodyAsText(msg *mail.Message) (string, *InvalidDocumentReason) { + body, err := io.ReadAll(msg.Body) + if err != nil { + r := InvalidDocumentRead + return "", &r + } + return string(body), nil +} + +// extractMultipartBody reads text parts from a multipart message and concatenates them. +func (s *EML) extractMultipartBody(msg *mail.Message, boundary string) (string, *InvalidDocumentReason) { + if boundary == "" { + r := InvalidDocumentRead + return "", &r + } + + body, err := io.ReadAll(msg.Body) + if err != nil { + r := InvalidDocumentRead + return "", &r + } + + mr := multipart.NewReader(bytes.NewReader(body), boundary) + var textContent strings.Builder + + for { + part, partErr := mr.NextPart() + if partErr != nil { + break + } + + partMedia := s.partMediaType(part) + if partMedia != "text/plain" && partMedia != "text/html" { + continue + } + + partData, readErr := io.ReadAll(part) + if readErr != nil { + continue + } + + text := s.textFromPart(partMedia, partData) + if textContent.Len() > 0 && text != "" { + textContent.WriteString("\n") + } + textContent.WriteString(text) + } + + return textContent.String(), nil +} + +// partMediaType extracts the media type from a MIME part's Content-Type header. +func (s *EML) partMediaType(part *multipart.Part) string { + ct := part.Header.Get("Content-Type") + if ct == "" { + return "text/plain" + } + parsed, _, err := mime.ParseMediaType(ct) + if err != nil { + return "text/plain" + } + return parsed +} + +// textFromPart converts a MIME part body to plain text. For text/html content, +// HTML tags are stripped. For text/plain, the content is returned as-is. +func (s *EML) textFromPart(mediaType string, data []byte) string { + if mediaType == "text/html" { + return stripHTMLTags(string(data)) + } + return string(data) +} + +// stripHTMLTags removes HTML tags from a string using a regex pattern, +// returning the plain text content. +func stripHTMLTags(html string) string { + return htmlTagPattern.ReplaceAllString(html, "") +} diff --git a/internal/document/types/eml_test.go b/internal/document/types/eml_test.go new file mode 100644 index 00000000..450ec04f --- /dev/null +++ b/internal/document/types/eml_test.go @@ -0,0 +1,148 @@ +package documenttypes + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestEML_ValidFile(t *testing.T) { + ctx := t.Context() + data, err := os.ReadFile("testdata/multiformat/valid.eml") + require.NoError(t, err) + + eml := NewEML(data) + + t.Run("IsCorrupt returns nil", func(t *testing.T) { + reason := eml.IsCorrupt(ctx) + assert.Nil(t, reason) + }) + + t.Run("GetPageCount returns 1", func(t *testing.T) { + count, err := eml.GetPageCount(ctx) + require.NoError(t, err) + assert.Equal(t, 1, count) + }) + + t.Run("GetPage returns body", func(t *testing.T) { + page, err := eml.GetPage(ctx, 0) + require.NoError(t, err) + assert.NotNil(t, page) + assert.Contains(t, string(page), "This is the body of the test email.") + }) +} + +func TestEML_InvalidHeaders(t *testing.T) { + ctx := t.Context() + // Random text without any RFC 822 headers or blank line separator. + data := []byte("This is just random text without any email headers at all.") + + eml := NewEML(data) + reason := eml.IsCorrupt(ctx) + require.NotNil(t, reason) + assert.Equal(t, InvalidDocumentMimeType, *reason) +} + +func TestEML_EmptyBody(t *testing.T) { + ctx := t.Context() + // Valid headers followed by empty body. + data := []byte("From: test@example.com\r\nTo: recipient@example.com\r\nSubject: Empty\r\nDate: Mon, 01 Jan 2024 00:00:00 +0000\r\n\r\n") + + eml := NewEML(data) + reason := eml.IsCorrupt(ctx) + require.NotNil(t, reason) + assert.Equal(t, InvalidDocumentEmptyContent, *reason) +} + +func TestEML_WithAttachment(t *testing.T) { + ctx := t.Context() + // Multipart EML with a text body and a binary attachment. + // Emails with attachments should be rejected -- uploader must strip before resubmitting. + data := []byte("From: test@example.com\r\n" + + "To: recipient@example.com\r\n" + + "Subject: Test\r\n" + + "Date: Mon, 01 Jan 2024 00:00:00 +0000\r\n" + + "MIME-Version: 1.0\r\n" + + "Content-Type: multipart/mixed; boundary=\"boundary123\"\r\n" + + "\r\n" + + "--boundary123\r\n" + + "Content-Type: text/plain\r\n" + + "\r\n" + + "This is the body.\r\n" + + "--boundary123\r\n" + + "Content-Type: application/pdf\r\n" + + "Content-Disposition: attachment; filename=\"test.pdf\"\r\n" + + "\r\n" + + "fake pdf data\r\n" + + "--boundary123--\r\n") + + eml := NewEML(data) + reason := eml.IsCorrupt(ctx) + + require.NotNil(t, reason) + assert.Equal(t, InvalidDocumentContainsAttachments, *reason) +} + +func TestEML_SinglePartNonText(t *testing.T) { + ctx := t.Context() + // Single-part message with binary content type should be rejected. + data := []byte("From: test@example.com\r\n" + + "To: recipient@example.com\r\n" + + "Subject: Binary\r\n" + + "Date: Mon, 01 Jan 2024 00:00:00 +0000\r\n" + + "Content-Type: application/pdf\r\n" + + "\r\n" + + "fake pdf content\r\n") + + eml := NewEML(data) + reason := eml.IsCorrupt(ctx) + + require.NotNil(t, reason) + assert.Equal(t, InvalidDocumentContainsAttachments, *reason, + "single-part non-text content should be rejected as attachment") +} + +func TestEML_SinglePartTextPlain(t *testing.T) { + ctx := t.Context() + // Single-part text/plain message should be accepted. + data := []byte("From: test@example.com\r\n" + + "To: recipient@example.com\r\n" + + "Subject: Plain text\r\n" + + "Date: Mon, 01 Jan 2024 00:00:00 +0000\r\n" + + "Content-Type: text/plain; charset=utf-8\r\n" + + "\r\n" + + "This is a plain text email body.\r\n") + + eml := NewEML(data) + reason := eml.IsCorrupt(ctx) + assert.Nil(t, reason, "single-part text/plain message should be valid") +} + +func TestEML_SinglePartTextHTML(t *testing.T) { + ctx := t.Context() + // Single-part text/html message should be accepted. + data := []byte("From: test@example.com\r\n" + + "To: recipient@example.com\r\n" + + "Subject: HTML email\r\n" + + "Date: Mon, 01 Jan 2024 00:00:00 +0000\r\n" + + "Content-Type: text/html; charset=utf-8\r\n" + + "\r\n" + + "

Hello world

\r\n") + + eml := NewEML(data) + reason := eml.IsCorrupt(ctx) + assert.Nil(t, reason, "single-part text/html message should be valid") +} + +func TestEML_GetPageInvalidIndex(t *testing.T) { + ctx := t.Context() + data, err := os.ReadFile("testdata/multiformat/valid.eml") + require.NoError(t, err) + + eml := NewEML(data) + _, pageErr := eml.GetPage(ctx, 1) + require.Error(t, pageErr) + assert.Contains(t, pageErr.Error(), "invalid page index") +} diff --git a/internal/document/types/image_common.go b/internal/document/types/image_common.go new file mode 100644 index 00000000..0f9c2ca3 --- /dev/null +++ b/internal/document/types/image_common.go @@ -0,0 +1,114 @@ +package documenttypes + +import ( + "image" + "image/color" +) + +// imageMaxFileSize is the maximum allowed file size for image files (500MB). +const imageMaxFileSize = 500 * 1024 * 1024 + +// isSolidColor samples the center pixel and 4 corners of an image, returning true +// if all sampled pixels are identical. This detects blank/empty image content. +func isSolidColor(img image.Image) bool { + bounds := img.Bounds() + w := bounds.Dx() + h := bounds.Dy() + if w == 0 || h == 0 { + return true + } + + // Sample points: center and 4 corners + points := []image.Point{ + {X: bounds.Min.X + w/2, Y: bounds.Min.Y + h/2}, + {X: bounds.Min.X, Y: bounds.Min.Y}, + {X: bounds.Max.X - 1, Y: bounds.Min.Y}, + {X: bounds.Min.X, Y: bounds.Max.Y - 1}, + {X: bounds.Max.X - 1, Y: bounds.Max.Y - 1}, + } + + ref := img.At(points[0].X, points[0].Y) + rr, rg, rb, ra := ref.RGBA() + + for _, p := range points[1:] { + c := img.At(p.X, p.Y) + cr, cg, cb, ca := c.RGBA() + if cr != rr || cg != rg || cb != rb || ca != ra { + return false + } + } + + return true +} + +// isFullyTransparent checks whether all sampled pixels have zero alpha, +// indicating the image has no visible content. +func isFullyTransparent(img image.Image) bool { + bounds := img.Bounds() + w := bounds.Dx() + h := bounds.Dy() + if w == 0 || h == 0 { + return true + } + + points := []image.Point{ + {X: bounds.Min.X + w/2, Y: bounds.Min.Y + h/2}, + {X: bounds.Min.X, Y: bounds.Min.Y}, + {X: bounds.Max.X - 1, Y: bounds.Min.Y}, + {X: bounds.Min.X, Y: bounds.Max.Y - 1}, + {X: bounds.Max.X - 1, Y: bounds.Max.Y - 1}, + } + + for _, p := range points { + _, _, _, a := img.At(p.X, p.Y).RGBA() + if a != 0 { + return false + } + } + + return true +} + +// invalidReason is a helper that returns a pointer to an InvalidDocumentReason. +func invalidReason(r InvalidDocumentReason) *InvalidDocumentReason { + return &r +} + +// checkImageDimensions validates width and height against Textract limits. +func checkImageDimensions(width, height int) *InvalidDocumentReason { + if width < TEXTRACT_MIN_DIMENSION || height < TEXTRACT_MIN_DIMENSION { + return invalidReason(InvalidDocumentSmallDimensions) + } + if width > TEXTRACT_MAX_DIMENSION || height > TEXTRACT_MAX_DIMENSION { + return invalidReason(InvalidDocumentLargeDimensions) + } + return nil +} + +// hasNonZeroPixelData checks whether an image has at least one non-zero pixel value. +func hasNonZeroPixelData(img image.Image) bool { + bounds := img.Bounds() + for y := bounds.Min.Y; y < bounds.Max.Y; y++ { + for x := bounds.Min.X; x < bounds.Max.X; x++ { + r, g, b, _ := img.At(x, y).RGBA() + if r != 0 || g != 0 || b != 0 { + return true + } + } + } + return false +} + +// colorModelHasAlpha returns true if the image's color model supports alpha transparency. +func colorModelHasAlpha(img image.Image) bool { + switch img.ColorModel() { + case color.NRGBAModel, color.NRGBA64Model, color.RGBAModel, color.RGBA64Model, color.AlphaModel, color.Alpha16Model: + return true + } + // Also check by concrete type for paletted images + switch img.(type) { + case *image.NRGBA, *image.NRGBA64, *image.RGBA, *image.RGBA64, *image.Alpha, *image.Alpha16: + return true + } + return false +} diff --git a/internal/document/types/invalid.go b/internal/document/types/invalid.go index 7dd13b2e..533d87dc 100644 --- a/internal/document/types/invalid.go +++ b/internal/document/types/invalid.go @@ -3,13 +3,19 @@ package documenttypes type InvalidDocumentReason string const ( - InvalidDocumentMimeType InvalidDocumentReason = "invalid_mimetype" - InvalidDocumentRead InvalidDocumentReason = "invalid_read" - InvalidDocumentReadPages InvalidDocumentReason = "invalid_read_pages" - InvalidDocumentZeroPageCount InvalidDocumentReason = "zero_page_count" - InvalidDocumentLargeFile InvalidDocumentReason = "large_file" - InvalidDocumentSmallDimensions InvalidDocumentReason = "small_dimensions" - InvalidDocumentLargeDimensions InvalidDocumentReason = "large_dimensions" - InvalidDocumentSmallDPI InvalidDocumentReason = "small_dpi" - InvalidDocumentLargeDPI InvalidDocumentReason = "large_dpi" + InvalidDocumentMimeType InvalidDocumentReason = "invalid_mimetype" + InvalidDocumentRead InvalidDocumentReason = "invalid_read" + InvalidDocumentReadPages InvalidDocumentReason = "invalid_read_pages" + InvalidDocumentZeroPageCount InvalidDocumentReason = "zero_page_count" + InvalidDocumentLargeFile InvalidDocumentReason = "large_file" + InvalidDocumentSmallDimensions InvalidDocumentReason = "small_dimensions" + InvalidDocumentLargeDimensions InvalidDocumentReason = "large_dimensions" + InvalidDocumentSmallDPI InvalidDocumentReason = "small_dpi" + InvalidDocumentLargeDPI InvalidDocumentReason = "large_dpi" + InvalidDocumentPasswordProtected InvalidDocumentReason = "password_protected" + InvalidDocumentContainsMacros InvalidDocumentReason = "contains_macros" + InvalidDocumentEmptyContent InvalidDocumentReason = "empty_content" + InvalidDocumentBinaryContent InvalidDocumentReason = "binary_content" + InvalidDocumentUnsupportedEncoding InvalidDocumentReason = "unsupported_encoding" + InvalidDocumentContainsAttachments InvalidDocumentReason = "contains_attachments" ) diff --git a/internal/document/types/jpeg.go b/internal/document/types/jpeg.go new file mode 100644 index 00000000..4fab082c --- /dev/null +++ b/internal/document/types/jpeg.go @@ -0,0 +1,194 @@ +package documenttypes + +import ( + "bytes" + "context" + "encoding/binary" + "fmt" + "image/jpeg" + "io" + "log/slog" + + "github.com/rwcarlsen/goexif/exif" +) + +// JPEG implements the File interface for JPEG image validation. +// It validates magic bytes, dimensions, DPI (via EXIF or JFIF), and content. +type JPEG struct { + data []byte +} + +// NewJPEGFromReader creates a new JPEG validator by reading all bytes from r. +func NewJPEGFromReader(r io.Reader) (*JPEG, error) { + data, err := io.ReadAll(r) + if err != nil { + return nil, err + } + return NewJPEG(data), nil +} + +// NewJPEG creates a new JPEG validator from raw file bytes. +func NewJPEG(data []byte) *JPEG { + return &JPEG{data: data} +} + +// IsCorrupt validates the JPEG file for corruption or unsupported content. +func (s *JPEG) IsCorrupt(_ context.Context) *InvalidDocumentReason { + if reason := s.checkMagicBytes(); reason != nil { + return reason + } + + img, err := jpeg.Decode(bytes.NewReader(s.data)) + if err != nil { + return invalidReason(InvalidDocumentRead) + } + + if len(s.data) > imageMaxFileSize { + return invalidReason(InvalidDocumentLargeFile) + } + + bounds := img.Bounds() + if reason := checkImageDimensions(bounds.Dx(), bounds.Dy()); reason != nil { + return reason + } + + if reason := s.checkDPI(); reason != nil { + return reason + } + + if isSolidColor(img) { + return invalidReason(InvalidDocumentEmptyContent) + } + + return nil +} + +// GetPageCount returns 1 since JPEG files are always single-page. +func (s *JPEG) GetPageCount(_ context.Context) (int, error) { + return 1, nil +} + +// GetPage returns the raw JPEG data for page index 0. +func (s *JPEG) GetPage(_ context.Context, index int) ([]byte, error) { + if index != 0 { + return nil, fmt.Errorf("jpeg: invalid page index %d: JPEG files have exactly 1 page", index) + } + return s.data, nil +} + +// checkMagicBytes verifies the JPEG SOI marker: FF D8 FF. +func (s *JPEG) checkMagicBytes() *InvalidDocumentReason { + if len(s.data) < 3 { + return invalidReason(InvalidDocumentMimeType) + } + if s.data[0] != 0xFF || s.data[1] != 0xD8 || s.data[2] != 0xFF { + return invalidReason(InvalidDocumentMimeType) + } + return nil +} + +// checkDPI attempts to read DPI from EXIF data first, then falls back to +// JFIF APP0 header parsing. Returns nil if DPI is acceptable or absent (defaults to 72). +func (s *JPEG) checkDPI() *InvalidDocumentReason { + xDPI, yDPI := s.getExifDPI() + if xDPI == 0 && yDPI == 0 { + xDPI, yDPI = s.getJFIFDPI() + } + + // Default to 72 if no DPI metadata found + if xDPI == 0 { + xDPI = float64(TEXTRACT_MIN_DPI) + } + if yDPI == 0 { + yDPI = float64(TEXTRACT_MIN_DPI) + } + + if xDPI < float64(TEXTRACT_MIN_DPI) || yDPI < float64(TEXTRACT_MIN_DPI) { + return invalidReason(InvalidDocumentSmallDPI) + } + + return nil +} + +// getExifDPI reads XResolution and YResolution from EXIF metadata. +// Returns (0, 0) if EXIF data is not present or cannot be read. +func (s *JPEG) getExifDPI() (xDPI, yDPI float64) { + x, err := exif.Decode(bytes.NewReader(s.data)) + if err != nil { + return 0, 0 + } + + xTag, err := x.Get(exif.XResolution) + if err == nil { + num, den, ratErr := xTag.Rat2(0) + if ratErr == nil && den != 0 { + xDPI = float64(num) / float64(den) + } + } + + yTag, err := x.Get(exif.YResolution) + if err == nil { + num, den, ratErr := yTag.Rat2(0) + if ratErr == nil && den != 0 { + yDPI = float64(num) / float64(den) + } + } + + // Check ResolutionUnit: 3 = dots per centimeter, convert to DPI + unitTag, err := x.Get(exif.ResolutionUnit) + if err == nil { + unitVal, intErr := unitTag.Int(0) + if intErr == nil && unitVal == 3 { + xDPI *= 2.54 + yDPI *= 2.54 + } + } + + return xDPI, yDPI +} + +// getJFIFDPI parses the JFIF APP0 header to extract DPI values. +// After FF D8, looks for FF E0 marker, skips length, checks "JFIF\0" identifier, +// reads density unit at offset 7, and XDensity/YDensity at offsets 8-11. +// Unit 1 = DPI, Unit 2 = DPCM (converted to DPI). +func (s *JPEG) getJFIFDPI() (xDPI, yDPI float64) { + // Minimum: SOI(2) + marker(2) + length(2) + JFIF\0(5) + version(2) + unit(1) + density(4) = 18 + if len(s.data) < 18 { + return 0, 0 + } + + // After SOI (FF D8), check for APP0 marker (FF E0) + if s.data[2] != 0xFF || s.data[3] != 0xE0 { + return 0, 0 + } + + // APP0 segment starts at offset 4 (after marker bytes) + segStart := 4 + segLen := int(binary.BigEndian.Uint16(s.data[segStart : segStart+2])) + if segStart+segLen > len(s.data) || segLen < 14 { + return 0, 0 + } + + // Check JFIF identifier: "JFIF\0" at segStart+2 + jfifID := s.data[segStart+2 : segStart+7] + if string(jfifID) != "JFIF\x00" { + return 0, 0 + } + + // Density unit at segStart+9 (offset 7 within segment data after length) + densityUnit := s.data[segStart+9] + xDensity := binary.BigEndian.Uint16(s.data[segStart+10 : segStart+12]) + yDensity := binary.BigEndian.Uint16(s.data[segStart+12 : segStart+14]) + + slog.Debug("jpeg: JFIF density", "unit", densityUnit, "x", xDensity, "y", yDensity) + + switch densityUnit { + case 1: // Dots per inch + return float64(xDensity), float64(yDensity) + case 2: // Dots per centimeter, convert to DPI + return float64(xDensity) * 2.54, float64(yDensity) * 2.54 + default: + // Unit 0 = no units (aspect ratio only), treat as no DPI info + return 0, 0 + } +} diff --git a/internal/document/types/jpeg_test.go b/internal/document/types/jpeg_test.go new file mode 100644 index 00000000..1977cfdd --- /dev/null +++ b/internal/document/types/jpeg_test.go @@ -0,0 +1,90 @@ +package documenttypes + +import ( + "bytes" + "image" + "image/color" + "image/jpeg" + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestJPEG_ValidFile(t *testing.T) { + data, err := os.ReadFile("testdata/multiformat/valid.jpeg") + require.NoError(t, err) + + j := NewJPEG(data) + ctx := t.Context() + + t.Run("IsCorrupt returns nil", func(t *testing.T) { + reason := j.IsCorrupt(ctx) + assert.Nil(t, reason) + }) + + t.Run("GetPageCount returns 1", func(t *testing.T) { + count, err := j.GetPageCount(ctx) + require.NoError(t, err) + assert.Equal(t, 1, count) + }) + + t.Run("GetPage(0) returns data", func(t *testing.T) { + page, err := j.GetPage(ctx, 0) + require.NoError(t, err) + assert.NotEmpty(t, page) + }) +} + +func TestJPEG_InvalidMagicBytes(t *testing.T) { + data := []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05} + j := NewJPEG(data) + + reason := j.IsCorrupt(t.Context()) + require.NotNil(t, reason) + assert.Equal(t, InvalidDocumentMimeType, *reason) +} + +func TestJPEG_SmallDimensions(t *testing.T) { + data, err := os.ReadFile("testdata/multiformat/small.jpeg") + require.NoError(t, err) + + j := NewJPEG(data) + reason := j.IsCorrupt(t.Context()) + require.NotNil(t, reason) + assert.Equal(t, InvalidDocumentSmallDimensions, *reason) +} + +func TestJPEG_CorruptData(t *testing.T) { + // Valid JPEG SOI marker (FF D8 FF) followed by garbage bytes. + data := make([]byte, 128) + data[0] = 0xFF + data[1] = 0xD8 + data[2] = 0xFF + // Rest is zeros -- not a decodable JPEG. + + j := NewJPEG(data) + reason := j.IsCorrupt(t.Context()) + require.NotNil(t, reason) + assert.Equal(t, InvalidDocumentRead, *reason) +} + +func TestJPEG_SolidColor(t *testing.T) { + // Generate a solid-color JPEG programmatically (100x100 all white). + img := image.NewRGBA(image.Rect(0, 0, 100, 100)) + white := color.RGBA{R: 255, G: 255, B: 255, A: 255} + for y := range 100 { + for x := range 100 { + img.Set(x, y, white) + } + } + var buf bytes.Buffer + err := jpeg.Encode(&buf, img, &jpeg.Options{Quality: 90}) + require.NoError(t, err) + + j := NewJPEG(buf.Bytes()) + reason := j.IsCorrupt(t.Context()) + require.NotNil(t, reason) + assert.Equal(t, InvalidDocumentEmptyContent, *reason) +} diff --git a/internal/document/types/office_common.go b/internal/document/types/office_common.go new file mode 100644 index 00000000..abbed51c --- /dev/null +++ b/internal/document/types/office_common.go @@ -0,0 +1,69 @@ +package documenttypes + +import ( + "archive/zip" + "bytes" + "fmt" + "io" + "strings" + + "github.com/richardlehane/mscfb" +) + +// officeMaxFileSize is the maximum allowed file size for Office documents (500MB). +const officeMaxFileSize = 500 * 1024 * 1024 + +// openOfficeZIP opens raw data as a ZIP archive and returns a zip.Reader. +// Returns an error if the data is not a valid ZIP. +func openOfficeZIP(data []byte) (*zip.Reader, error) { + return zip.NewReader(bytes.NewReader(data), int64(len(data))) +} + +// hasVBAMacros scans ZIP entries for vbaProject.bin in any path, +// indicating the document contains VBA macros. +func hasVBAMacros(zr *zip.Reader) bool { + for _, f := range zr.File { + if strings.HasSuffix(strings.ToLower(f.Name), "vbaproject.bin") { + return true + } + } + return false +} + +// IsOLE2Encrypted checks if data starts with the OLE2 compound document signature +// and contains an EncryptedPackage stream, which indicates an encrypted OOXML document. +func IsOLE2Encrypted(data []byte) bool { + // OLE2 signature: D0 CF 11 E0 A1 B1 1A E1 + ole2Sig := []byte{0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1} + if len(data) < len(ole2Sig) || !bytes.Equal(data[:len(ole2Sig)], ole2Sig) { + return false + } + + doc, err := mscfb.New(bytes.NewReader(data)) + if err != nil { + return false + } + + for entry, err := doc.Next(); err == nil; entry, err = doc.Next() { + if entry.Name == "EncryptedPackage" { + return true + } + } + + return false +} + +// readZIPFile reads and returns the contents of a named file within a ZIP archive. +func readZIPFile(zr *zip.Reader, name string) ([]byte, error) { + for _, f := range zr.File { + if f.Name == name { + rc, err := f.Open() + if err != nil { + return nil, fmt.Errorf("failed to open %s: %w", name, err) + } + defer rc.Close() + return io.ReadAll(rc) + } + } + return nil, fmt.Errorf("file %s not found in ZIP", name) +} diff --git a/internal/document/types/office_common_test.go b/internal/document/types/office_common_test.go new file mode 100644 index 00000000..044690ca --- /dev/null +++ b/internal/document/types/office_common_test.go @@ -0,0 +1,83 @@ +package documenttypes + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestOpenOfficeZIP_Valid(t *testing.T) { + data, err := os.ReadFile("testdata/multiformat/valid.docx") + require.NoError(t, err) + + zr, err := openOfficeZIP(data) + require.NoError(t, err) + assert.NotNil(t, zr) + assert.Greater(t, len(zr.File), 0, "ZIP should contain entries") +} + +func TestOpenOfficeZIP_Invalid(t *testing.T) { + garbage := []byte("this is not a zip file at all") + + zr, err := openOfficeZIP(garbage) + assert.Error(t, err) + assert.Nil(t, zr) +} + +func TestHasVBAMacros_WithMacros(t *testing.T) { + data, err := os.ReadFile("testdata/multiformat/macro.docx") + require.NoError(t, err) + + zr, err := openOfficeZIP(data) + require.NoError(t, err) + + assert.True(t, hasVBAMacros(zr), "macro.docx should contain VBA macros") +} + +func TestHasVBAMacros_WithoutMacros(t *testing.T) { + data, err := os.ReadFile("testdata/multiformat/valid.docx") + require.NoError(t, err) + + zr, err := openOfficeZIP(data) + require.NoError(t, err) + + assert.False(t, hasVBAMacros(zr), "valid.docx should not contain VBA macros") +} + +func TestIsOLE2Encrypted(t *testing.T) { + t.Run("OLE2 signature without valid structure returns false", func(t *testing.T) { + // encrypted.docx has the OLE2 signature bytes but is not a fully valid + // OLE2 compound document with an EncryptedPackage stream, so + // IsOLE2Encrypted returns false (mscfb cannot parse it). + data, err := os.ReadFile("testdata/multiformat/encrypted.docx") + require.NoError(t, err) + + // Verify it does start with OLE2 signature + ole2Sig := []byte{0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1} + require.True(t, len(data) >= len(ole2Sig)) + assert.Equal(t, ole2Sig, data[:len(ole2Sig)], "fixture should start with OLE2 signature") + + // But the file is not a parseable OLE2 compound document + assert.False(t, IsOLE2Encrypted(data), + "malformed OLE2 file should not be detected as encrypted") + }) + + t.Run("valid docx returns false", func(t *testing.T) { + data, err := os.ReadFile("testdata/multiformat/valid.docx") + require.NoError(t, err) + + assert.False(t, IsOLE2Encrypted(data), "valid.docx should not be detected as OLE2 encrypted") + }) + + t.Run("garbage bytes return false", func(t *testing.T) { + data := []byte("not ole2 at all") + assert.False(t, IsOLE2Encrypted(data)) + }) + + t.Run("too short returns false", func(t *testing.T) { + data := []byte{0xD0, 0xCF} + assert.False(t, IsOLE2Encrypted(data)) + }) +} diff --git a/internal/document/types/parsetype.go b/internal/document/types/parsetype.go index 654af8c3..f6f17cd3 100644 --- a/internal/document/types/parsetype.go +++ b/internal/document/types/parsetype.go @@ -6,6 +6,24 @@ func ToDBMimeType(t MimeType) repository.Cleanmimetype { switch t { case MimeTypePDF: return repository.CleanmimetypeApplicationPdf + case MimeTypeTIFF: + return repository.CleanmimetypeImageTiff + case MimeTypeJPEG: + return repository.CleanmimetypeImageJpeg + case MimeTypePNG: + return repository.CleanmimetypeImagePng + case MimeTypeBMP: + return repository.CleanmimetypeImageBmp + case MimeTypeDOCX: + return repository.CleanmimetypeApplicationDocx + case MimeTypeXLSX: + return repository.CleanmimetypeApplicationXlsx + case MimeTypePPTX: + return repository.CleanmimetypeApplicationPptx + case MimeTypeTXT: + return repository.CleanmimetypeTextPlain + case MimeTypeEML: + return repository.CleanmimetypeMessageRfc822 } return repository.Cleanmimetype("") @@ -15,6 +33,24 @@ func ParseDBMimeType(t repository.Cleanmimetype) MimeType { switch t { case repository.CleanmimetypeApplicationPdf: return MimeTypePDF + case repository.CleanmimetypeImageTiff: + return MimeTypeTIFF + case repository.CleanmimetypeImageJpeg: + return MimeTypeJPEG + case repository.CleanmimetypeImagePng: + return MimeTypePNG + case repository.CleanmimetypeImageBmp: + return MimeTypeBMP + case repository.CleanmimetypeApplicationDocx: + return MimeTypeDOCX + case repository.CleanmimetypeApplicationXlsx: + return MimeTypeXLSX + case repository.CleanmimetypeApplicationPptx: + return MimeTypePPTX + case repository.CleanmimetypeTextPlain: + return MimeTypeTXT + case repository.CleanmimetypeMessageRfc822: + return MimeTypeEML } return MimeTypeInvalid @@ -40,6 +76,18 @@ func ToDBFailType(t InvalidDocumentReason) repository.Cleanfailtype { return repository.CleanfailtypeSmallDpi case InvalidDocumentLargeDPI: return repository.CleanfailtypeLargeDpi + case InvalidDocumentPasswordProtected: + return repository.CleanfailtypePasswordProtected + case InvalidDocumentContainsMacros: + return repository.CleanfailtypeContainsMacros + case InvalidDocumentEmptyContent: + return repository.CleanfailtypeEmptyContent + case InvalidDocumentBinaryContent: + return repository.CleanfailtypeBinaryContent + case InvalidDocumentUnsupportedEncoding: + return repository.CleanfailtypeUnsupportedEncoding + case InvalidDocumentContainsAttachments: + return repository.CleanfailtypeContainsAttachments } return repository.Cleanfailtype("") @@ -65,6 +113,18 @@ func ParseDBFailType(t repository.Cleanfailtype) InvalidDocumentReason { return InvalidDocumentSmallDPI case repository.CleanfailtypeLargeDpi: return InvalidDocumentLargeDPI + case repository.CleanfailtypePasswordProtected: + return InvalidDocumentPasswordProtected + case repository.CleanfailtypeContainsMacros: + return InvalidDocumentContainsMacros + case repository.CleanfailtypeEmptyContent: + return InvalidDocumentEmptyContent + case repository.CleanfailtypeBinaryContent: + return InvalidDocumentBinaryContent + case repository.CleanfailtypeUnsupportedEncoding: + return InvalidDocumentUnsupportedEncoding + case repository.CleanfailtypeContainsAttachments: + return InvalidDocumentContainsAttachments } return InvalidDocumentReason("") diff --git a/internal/document/types/png.go b/internal/document/types/png.go new file mode 100644 index 00000000..543a9fc2 --- /dev/null +++ b/internal/document/types/png.go @@ -0,0 +1,173 @@ +package documenttypes + +import ( + "bytes" + "context" + "encoding/binary" + "fmt" + "image/png" + "io" + "log/slog" +) + +// pngPixelBudget is the maximum allowed pixel count (width * height) for PNG files. +const pngPixelBudget = 100_000_000 + +// PNG implements the File interface for PNG image validation. +// It validates magic bytes, dimensions, pixel budget, DPI (via pHYs chunk), and content. +type PNG struct { + data []byte +} + +// NewPNGFromReader creates a new PNG validator by reading all bytes from r. +func NewPNGFromReader(r io.Reader) (*PNG, error) { + data, err := io.ReadAll(r) + if err != nil { + return nil, err + } + return NewPNG(data), nil +} + +// NewPNG creates a new PNG validator from raw file bytes. +func NewPNG(data []byte) *PNG { + return &PNG{data: data} +} + +// IsCorrupt validates the PNG file for corruption or unsupported content. +func (s *PNG) IsCorrupt(_ context.Context) *InvalidDocumentReason { + if reason := s.checkMagicBytes(); reason != nil { + return reason + } + + // Pre-check IHDR dimensions before decoding to prevent decompression bombs. + // IHDR is always the first chunk after the 8-byte PNG signature: + // bytes 16-19 = width, bytes 20-23 = height (big-endian uint32). + if len(s.data) < 24 { + return invalidReason(InvalidDocumentRead) + } + ihdrWidth := binary.BigEndian.Uint32(s.data[16:20]) + ihdrHeight := binary.BigEndian.Uint32(s.data[20:24]) + if int64(ihdrWidth)*int64(ihdrHeight) > pngPixelBudget { + return invalidReason(InvalidDocumentLargeFile) + } + + img, err := png.Decode(bytes.NewReader(s.data)) + if err != nil { + return invalidReason(InvalidDocumentRead) + } + + if len(s.data) > imageMaxFileSize { + return invalidReason(InvalidDocumentLargeFile) + } + + bounds := img.Bounds() + width := bounds.Dx() + height := bounds.Dy() + + if reason := checkImageDimensions(width, height); reason != nil { + return reason + } + + if reason := s.checkDPI(); reason != nil { + return reason + } + + // Check for fully transparent images (PNG-specific alpha check) + if colorModelHasAlpha(img) && isFullyTransparent(img) { + return invalidReason(InvalidDocumentEmptyContent) + } + + if isSolidColor(img) { + return invalidReason(InvalidDocumentEmptyContent) + } + + return nil +} + +// GetPageCount returns 1 since PNG files are always single-page. +func (s *PNG) GetPageCount(_ context.Context) (int, error) { + return 1, nil +} + +// GetPage returns the raw PNG data for page index 0. +func (s *PNG) GetPage(_ context.Context, index int) ([]byte, error) { + if index != 0 { + return nil, fmt.Errorf("png: invalid page index %d: PNG files have exactly 1 page", index) + } + return s.data, nil +} + +// checkMagicBytes verifies the 8-byte PNG signature: 89 50 4E 47 0D 0A 1A 0A. +func (s *PNG) checkMagicBytes() *InvalidDocumentReason { + pngSig := []byte{0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A} + if len(s.data) < len(pngSig) { + return invalidReason(InvalidDocumentMimeType) + } + if !bytes.Equal(s.data[:len(pngSig)], pngSig) { + return invalidReason(InvalidDocumentMimeType) + } + return nil +} + +// checkDPI reads the pHYs chunk from PNG data to determine DPI. +// Returns nil if DPI is acceptable or if no pHYs chunk is present (defaults to 72). +func (s *PNG) checkDPI() *InvalidDocumentReason { + xDPI, yDPI := s.parsePHYsChunk() + + // Default to 72 if no pHYs chunk found + if xDPI == 0 { + xDPI = float64(TEXTRACT_MIN_DPI) + } + if yDPI == 0 { + yDPI = float64(TEXTRACT_MIN_DPI) + } + + if xDPI < float64(TEXTRACT_MIN_DPI) || yDPI < float64(TEXTRACT_MIN_DPI) { + return invalidReason(InvalidDocumentSmallDPI) + } + + return nil +} + +// parsePHYsChunk iterates PNG chunks after the 8-byte signature looking for "pHYs". +// Each chunk: 4 bytes length + 4 bytes type + data + 4 bytes CRC. +// pHYs data: 4 bytes X pixels per unit, 4 bytes Y pixels per unit, 1 byte unit type. +// Unit 1 = meter; conversion: dpi = ppu / 39.3701. +func (s *PNG) parsePHYsChunk() (xDPI, yDPI float64) { + // PNG signature is 8 bytes, minimum chunk is 12 bytes (4 len + 4 type + 4 CRC) + if len(s.data) < 20 { + return 0, 0 + } + + offset := 8 // Skip PNG signature + for offset+12 <= len(s.data) { + chunkLen := binary.BigEndian.Uint32(s.data[offset : offset+4]) + chunkType := string(s.data[offset+4 : offset+8]) + + // Ensure we have enough data for the chunk + chunkEnd := offset + 12 + int(chunkLen) + if chunkEnd > len(s.data) { + break + } + + if chunkType == "pHYs" && chunkLen == 9 { + dataStart := offset + 8 + xPPU := binary.BigEndian.Uint32(s.data[dataStart : dataStart+4]) + yPPU := binary.BigEndian.Uint32(s.data[dataStart+4 : dataStart+8]) + unit := s.data[dataStart+8] + + slog.Debug("png: pHYs chunk", "xPPU", xPPU, "yPPU", yPPU, "unit", unit) + + if unit == 1 { // Meter + return float64(xPPU) / 39.3701, float64(yPPU) / 39.3701 + } + // Unit 0 = unknown, no conversion possible + return 0, 0 + } + + // Move past this chunk: 4 (length) + 4 (type) + chunkLen (data) + 4 (CRC) + offset = chunkEnd + } + + return 0, 0 +} diff --git a/internal/document/types/png_test.go b/internal/document/types/png_test.go new file mode 100644 index 00000000..069fdf81 --- /dev/null +++ b/internal/document/types/png_test.go @@ -0,0 +1,91 @@ +package documenttypes + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestPNG_ValidFile(t *testing.T) { + data, err := os.ReadFile("testdata/multiformat/valid.png") + require.NoError(t, err) + + p := NewPNG(data) + ctx := t.Context() + + t.Run("IsCorrupt returns nil", func(t *testing.T) { + reason := p.IsCorrupt(ctx) + assert.Nil(t, reason) + }) + + t.Run("GetPageCount returns 1", func(t *testing.T) { + count, err := p.GetPageCount(ctx) + require.NoError(t, err) + assert.Equal(t, 1, count) + }) +} + +func TestPNG_InvalidMagicBytes(t *testing.T) { + data := []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09} + p := NewPNG(data) + + reason := p.IsCorrupt(t.Context()) + require.NotNil(t, reason) + assert.Equal(t, InvalidDocumentMimeType, *reason) +} + +func TestPNG_SolidColor(t *testing.T) { + data, err := os.ReadFile("testdata/multiformat/solid_color.png") + require.NoError(t, err) + + p := NewPNG(data) + reason := p.IsCorrupt(t.Context()) + require.NotNil(t, reason) + assert.Equal(t, InvalidDocumentEmptyContent, *reason) +} + +func TestPNG_DecompressionBomb(t *testing.T) { + // Craft a minimal PNG with valid signature and IHDR declaring enormous + // dimensions (50000x50000 = 2.5 billion pixels) but a tiny file size. + // The IHDR pre-check should reject this before attempting full decode. + data := make([]byte, 64) + // PNG signature + copy(data[0:8], []byte{0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A}) + // IHDR chunk: length=13, type="IHDR" + data[8] = 0x00 + data[9] = 0x00 + data[10] = 0x00 + data[11] = 0x0D + copy(data[12:16], []byte("IHDR")) + // Width: 50000 (0x0000C350) big-endian + data[16] = 0x00 + data[17] = 0x00 + data[18] = 0xC3 + data[19] = 0x50 + // Height: 50000 (0x0000C350) big-endian + data[20] = 0x00 + data[21] = 0x00 + data[22] = 0xC3 + data[23] = 0x50 + + p := NewPNG(data) + reason := p.IsCorrupt(t.Context()) + require.NotNil(t, reason) + assert.Equal(t, InvalidDocumentLargeFile, *reason, + "PNG with enormous IHDR dimensions should be rejected before decode") +} + +func TestPNG_CorruptData(t *testing.T) { + // Valid 8-byte PNG signature followed by garbage data. + data := make([]byte, 128) + // PNG signature: 89 50 4E 47 0D 0A 1A 0A + copy(data, []byte{0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A}) + // Remaining bytes are zeros -- not a valid PNG stream. + + p := NewPNG(data) + reason := p.IsCorrupt(t.Context()) + require.NotNil(t, reason) + assert.Equal(t, InvalidDocumentRead, *reason) +} diff --git a/internal/document/types/pptx.go b/internal/document/types/pptx.go new file mode 100644 index 00000000..451a2728 --- /dev/null +++ b/internal/document/types/pptx.go @@ -0,0 +1,245 @@ +package documenttypes + +import ( + "archive/zip" + "context" + "encoding/xml" + "strings" +) + +// PPTX represents a PowerPoint OOXML presentation for validation and slide extraction. +type PPTX struct { + data []byte +} + +// NewPPTX creates a new PPTX validator from raw file data. +func NewPPTX(data []byte) *PPTX { + return &PPTX{data: data} +} + +// pptxPresentation is a minimal XML representation of ppt/presentation.xml, +// capturing the modify verifier for encryption detection. +type pptxPresentation struct { + XMLName xml.Name `xml:"presentation"` + ModifyVerifier *pptxModifyVerifier `xml:"modifyVerifier"` +} + +type pptxModifyVerifier struct { + CryptProviderType string `xml:"cryptProviderType,attr"` + CryptAlgorithmSid string `xml:"cryptAlgorithmSid,attr"` + HashData string `xml:"hashData,attr"` + SaltData string `xml:"saltData,attr"` +} + +// pptxSlide is a minimal XML representation of a slide, +// capturing text runs, pictures, and graphic frames to detect content. +type pptxSlide struct { + XMLName xml.Name `xml:"sld"` + CSld pptxCSld `xml:"cSld"` +} + +type pptxCSld struct { + SpTree pptxSpTree `xml:"spTree"` +} + +type pptxSpTree struct { + Shapes []pptxShape `xml:"sp"` + Pictures []struct{} `xml:"pic"` + GraphicFrames []struct{} `xml:"graphicFrame"` +} + +type pptxShape struct { + TxBody *pptxTxBody `xml:"txBody"` +} + +type pptxTxBody struct { + Paragraphs []pptxParagraph `xml:"p"` +} + +type pptxParagraph struct { + Runs []pptxRun `xml:"r"` +} + +type pptxRun struct { + Text string `xml:"t"` +} + +// IsCorrupt validates the PPTX document, returning the reason it is invalid +// or nil if the document passes all checks. +func (s *PPTX) IsCorrupt(_ context.Context) *InvalidDocumentReason { + // 1. Check for OLE2 encryption (encrypted OOXML files use OLE2 wrapper) + if IsOLE2Encrypted(s.data) { + reason := InvalidDocumentPasswordProtected + return &reason + } + + // 2. Check ZIP signature + if !hasZIPSignature(s.data) { + reason := InvalidDocumentMimeType + return &reason + } + + // 3. Open ZIP and verify content type + zr, err := openOfficeZIP(s.data) + if err != nil { + reason := InvalidDocumentMimeType + return &reason + } + + ct, err := readZIPFile(zr, "[Content_Types].xml") + if err != nil || !strings.Contains(string(ct), "presentationml.presentation.main+xml") { + reason := InvalidDocumentMimeType + return &reason + } + + // 4. Reject if macros are present + if hasVBAMacros(zr) { + reason := InvalidDocumentContainsMacros + return &reason + } + if r := s.hasPasswordProtection(zr); r != nil { + return r + } + + // 5. Verify presentation.xml exists and parses; at least one slide exists + if r := s.validateStructure(zr); r != nil { + return r + } + + // 6. File size check + if len(s.data) > officeMaxFileSize { + reason := InvalidDocumentLargeFile + return &reason + } + + // 7. Content check + if !s.hasContent(zr) { + reason := InvalidDocumentEmptyContent + return &reason + } + + // 8. Slide count check + slideCount := s.countSlides(zr) + if slideCount < 1 { + reason := InvalidDocumentZeroPageCount + return &reason + } + + return nil +} + +// GetPageCount returns the number of slides in the presentation. +func (s *PPTX) GetPageCount(_ context.Context) (int, error) { + zr, err := openOfficeZIP(s.data) + if err != nil { + return 0, err + } + + count := max(s.countSlides(zr), 1) + return count, nil +} + +// GetPage returns the raw presentation bytes for the requested page index. +func (s *PPTX) GetPage(_ context.Context, _ int) ([]byte, error) { + return s.data, nil +} + +// hasPasswordProtection checks ppt/presentation.xml for modifyVerifier +// elements indicating password protection. +func (s *PPTX) hasPasswordProtection(zr *zip.Reader) *InvalidDocumentReason { + presXML, err := readZIPFile(zr, "ppt/presentation.xml") + if err != nil { + return nil + } + + var pres pptxPresentation + if xmlErr := xml.Unmarshal(presXML, &pres); xmlErr != nil { + return nil + } + + if pres.ModifyVerifier != nil && + (pres.ModifyVerifier.CryptProviderType != "" || + pres.ModifyVerifier.HashData != "" || + pres.ModifyVerifier.SaltData != "") { + reason := InvalidDocumentPasswordProtected + return &reason + } + + return nil +} + +// validateStructure verifies that ppt/presentation.xml exists and parses, +// and at least one slide XML file is present. +func (s *PPTX) validateStructure(zr *zip.Reader) *InvalidDocumentReason { + presXML, err := readZIPFile(zr, "ppt/presentation.xml") + if err != nil { + reason := InvalidDocumentRead + return &reason + } + + var pres pptxPresentation + if xmlErr := xml.Unmarshal(presXML, &pres); xmlErr != nil { + reason := InvalidDocumentRead + return &reason + } + + if s.countSlides(zr) < 1 { + reason := InvalidDocumentRead + return &reason + } + + return nil +} + +// hasContent checks whether any slide has text content, pictures, or graphic frames. +func (s *PPTX) hasContent(zr *zip.Reader) bool { + for _, f := range zr.File { + if !strings.HasPrefix(f.Name, "ppt/slides/slide") || + !strings.HasSuffix(f.Name, ".xml") { + continue + } + + slideXML, err := readZIPFile(zr, f.Name) + if err != nil { + continue + } + + var slide pptxSlide + if xmlErr := xml.Unmarshal(slideXML, &slide); xmlErr != nil { + continue + } + + // Check for pictures or graphic frames + if len(slide.CSld.SpTree.Pictures) > 0 || len(slide.CSld.SpTree.GraphicFrames) > 0 { + return true + } + + // Check for text content in shapes + for _, sp := range slide.CSld.SpTree.Shapes { + if sp.TxBody == nil { + continue + } + for _, p := range sp.TxBody.Paragraphs { + for _, r := range p.Runs { + if strings.TrimSpace(r.Text) != "" { + return true + } + } + } + } + } + + return false +} + +// countSlides counts the number of ppt/slides/slide*.xml entries in the ZIP. +func (s *PPTX) countSlides(zr *zip.Reader) int { + count := 0 + for _, f := range zr.File { + if strings.HasPrefix(f.Name, "ppt/slides/slide") && + strings.HasSuffix(f.Name, ".xml") { + count++ + } + } + return count +} diff --git a/internal/document/types/pptx_test.go b/internal/document/types/pptx_test.go new file mode 100644 index 00000000..3f27e995 --- /dev/null +++ b/internal/document/types/pptx_test.go @@ -0,0 +1,61 @@ +package documenttypes + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestPPTX_ValidFile(t *testing.T) { + ctx := t.Context() + data, err := os.ReadFile("testdata/multiformat/valid.pptx") + require.NoError(t, err) + + pptx := NewPPTX(data) + + t.Run("IsCorrupt returns nil", func(t *testing.T) { + reason := pptx.IsCorrupt(ctx) + assert.Nil(t, reason, "valid.pptx should not be corrupt") + }) + + t.Run("GetPageCount >= 1", func(t *testing.T) { + count, err := pptx.GetPageCount(ctx) + require.NoError(t, err) + assert.GreaterOrEqual(t, count, 1) + }) + + t.Run("GetPage returns data", func(t *testing.T) { + page, err := pptx.GetPage(ctx, 0) + require.NoError(t, err) + assert.NotEmpty(t, page) + }) +} + +func TestPPTX_InvalidMagicBytes(t *testing.T) { + ctx := t.Context() + data := []byte("this is not a ZIP or PPTX file") + + pptx := NewPPTX(data) + reason := pptx.IsCorrupt(ctx) + + require.NotNil(t, reason) + assert.Equal(t, InvalidDocumentMimeType, *reason) +} + +func TestPPTX_Encrypted(t *testing.T) { + // encrypted.docx has the OLE2 signature but is not a parseable OLE2 compound + // document (malformed fixture). IsOLE2Encrypted returns false, then the ZIP + // signature check fails, so it returns InvalidDocumentMimeType. + ctx := t.Context() + data, err := os.ReadFile("testdata/multiformat/encrypted.docx") + require.NoError(t, err) + + pptx := NewPPTX(data) + reason := pptx.IsCorrupt(ctx) + + require.NotNil(t, reason) + assert.Equal(t, InvalidDocumentMimeType, *reason, + "malformed OLE2 file should fail ZIP signature check") +} diff --git a/internal/document/types/testdata/generate_fixtures.go b/internal/document/types/testdata/generate_fixtures.go new file mode 100644 index 00000000..8141b7b5 --- /dev/null +++ b/internal/document/types/testdata/generate_fixtures.go @@ -0,0 +1,491 @@ +//go:build ignore + +// generate_fixtures.go creates minimal but valid test fixture files for +// document format testing. Run with: +// +// go run internal/document/types/testdata/generate_fixtures.go +package main + +import ( + "archive/zip" + "bytes" + "fmt" + "image" + "image/color" + "image/jpeg" + "image/png" + "os" + "path/filepath" + + tiff "github.com/chai2010/tiff" + "golang.org/x/image/bmp" +) + +// outDir is the directory where all fixtures will be written. +const outDir = "internal/document/types/testdata/multiformat" + +func main() { + if err := os.MkdirAll(outDir, 0o755); err != nil { + fatal("create output dir", err) + } + + generators := []struct { + name string + fn func() error + }{ + {"valid.tiff", genValidTIFF}, + {"valid.jpeg", genValidJPEG}, + {"valid.png", genValidPNG}, + {"valid.bmp", genValidBMP}, + {"valid.docx", genValidDOCX}, + {"valid.xlsx", genValidXLSX}, + {"valid.pptx", genValidPPTX}, + {"valid.txt", genValidTXT}, + {"valid.eml", genValidEML}, + {"empty.txt", genEmptyTXT}, + {"binary.txt", genBinaryTXT}, + {"encrypted.docx", genEncryptedDOCX}, + {"solid_color.png", genSolidColorPNG}, + {"small.jpeg", genSmallJPEG}, + {"macro.docx", genMacroDOCX}, + } + + for _, g := range generators { + fmt.Printf("generating %s ... ", g.name) + if err := g.fn(); err != nil { + fatal(g.name, err) + } + info, err := os.Stat(filepath.Join(outDir, g.name)) + if err != nil { + fatal(g.name+" stat", err) + } + fmt.Printf("OK (%d bytes)\n", info.Size()) + } + + fmt.Println("\nAll fixtures generated successfully.") +} + +// --------------------------------------------------------------------------- +// Helpers +// --------------------------------------------------------------------------- + +func fatal(context string, err error) { + fmt.Fprintf(os.Stderr, "FATAL [%s]: %v\n", context, err) + os.Exit(1) +} + +// writeFile writes data to outDir/name. +func writeFile(name string, data []byte) error { + return os.WriteFile(filepath.Join(outDir, name), data, 0o644) +} + +// newTestImage creates a 100x100 white image with a red rectangle in the +// centre (40,40)-(60,60) so it passes solid-color detection checks. +func newTestImage(width, height int) *image.NRGBA { + img := image.NewNRGBA(image.Rect(0, 0, width, height)) + white := color.NRGBA{R: 255, G: 255, B: 255, A: 255} + red := color.NRGBA{R: 255, G: 0, B: 0, A: 255} + + // Fill white background. + for y := 0; y < height; y++ { + for x := 0; x < width; x++ { + img.SetNRGBA(x, y, white) + } + } + // Draw red rectangle in the centre. + cx, cy := width/2, height/2 + for y := cy - height/5; y < cy+height/5; y++ { + for x := cx - width/5; x < cx+width/5; x++ { + if x >= 0 && x < width && y >= 0 && y < height { + img.SetNRGBA(x, y, red) + } + } + } + return img +} + +// createZipFile builds a ZIP archive from the given entries and writes it. +func createZipFile(name string, entries []zipEntry) error { + var buf bytes.Buffer + zw := zip.NewWriter(&buf) + + for _, e := range entries { + fw, err := zw.Create(e.Name) + if err != nil { + return fmt.Errorf("zip create %s: %w", e.Name, err) + } + if _, err := fw.Write([]byte(e.Body)); err != nil { + return fmt.Errorf("zip write %s: %w", e.Name, err) + } + } + if err := zw.Close(); err != nil { + return fmt.Errorf("zip close: %w", err) + } + return writeFile(name, buf.Bytes()) +} + +type zipEntry struct { + Name string + Body string +} + +// --------------------------------------------------------------------------- +// Valid image fixtures +// --------------------------------------------------------------------------- + +func genValidTIFF() error { + img := newTestImage(100, 100) + var buf bytes.Buffer + if err := tiff.Encode(&buf, img, nil); err != nil { + return err + } + return writeFile("valid.tiff", buf.Bytes()) +} + +func genValidJPEG() error { + img := newTestImage(100, 100) + var buf bytes.Buffer + if err := jpeg.Encode(&buf, img, &jpeg.Options{Quality: 90}); err != nil { + return err + } + return writeFile("valid.jpeg", buf.Bytes()) +} + +func genValidPNG() error { + img := newTestImage(100, 100) + var buf bytes.Buffer + if err := png.Encode(&buf, img); err != nil { + return err + } + return writeFile("valid.png", buf.Bytes()) +} + +func genValidBMP() error { + img := newTestImage(100, 100) + var buf bytes.Buffer + if err := bmp.Encode(&buf, img); err != nil { + return err + } + return writeFile("valid.bmp", buf.Bytes()) +} + +// --------------------------------------------------------------------------- +// Valid Office fixtures +// --------------------------------------------------------------------------- + +func genValidDOCX() error { + return createZipFile("valid.docx", []zipEntry{ + { + Name: "[Content_Types].xml", + Body: ` + + + + +`, + }, + { + Name: "_rels/.rels", + Body: ` + + +`, + }, + { + Name: "word/_rels/document.xml.rels", + Body: ` + +`, + }, + { + Name: "word/document.xml", + Body: ` + + + + + Test document content + + + +`, + }, + }) +} + +func genValidXLSX() error { + return createZipFile("valid.xlsx", []zipEntry{ + { + Name: "[Content_Types].xml", + Body: ` + + + + + + +`, + }, + { + Name: "_rels/.rels", + Body: ` + + +`, + }, + { + Name: "xl/_rels/workbook.xml.rels", + Body: ` + + + +`, + }, + { + Name: "xl/workbook.xml", + Body: ` + + + + +`, + }, + { + Name: "xl/worksheets/sheet1.xml", + Body: ` + + + + 0 + + +`, + }, + { + Name: "xl/sharedStrings.xml", + Body: ` + + Test data +`, + }, + }) +} + +func genValidPPTX() error { + return createZipFile("valid.pptx", []zipEntry{ + { + Name: "[Content_Types].xml", + Body: ` + + + + + +`, + }, + { + Name: "_rels/.rels", + Body: ` + + +`, + }, + { + Name: "ppt/_rels/presentation.xml.rels", + Body: ` + + +`, + }, + { + Name: "ppt/presentation.xml", + Body: ` + + + + +`, + }, + { + Name: "ppt/slides/_rels/slide1.xml.rels", + Body: ` + +`, + }, + { + Name: "ppt/slides/slide1.xml", + Body: ` + + + + + + + + + + + + + + + + + + + + Test slide content + + + + +`, + }, + }) +} + +// --------------------------------------------------------------------------- +// Valid text fixtures +// --------------------------------------------------------------------------- + +func genValidTXT() error { + return writeFile("valid.txt", []byte("Hello, this is a test document.\nIt has multiple lines.\n")) +} + +func genValidEML() error { + content := "From: sender@example.com\r\n" + + "To: recipient@example.com\r\n" + + "Subject: Test Email\r\n" + + "Date: Mon, 01 Jan 2024 00:00:00 +0000\r\n" + + "Content-Type: text/plain; charset=\"utf-8\"\r\n" + + "\r\n" + + "This is the body of the test email.\r\n" + return writeFile("valid.eml", []byte(content)) +} + +// --------------------------------------------------------------------------- +// Invalid / edge-case fixtures +// --------------------------------------------------------------------------- + +func genEmptyTXT() error { + return writeFile("empty.txt", []byte{}) +} + +func genBinaryTXT() error { + // Mix of printable text and null bytes. + data := []byte("Hello\x00World\x00\x00This has\x00null bytes\x00inside") + return writeFile("binary.txt", data) +} + +func genEncryptedDOCX() error { + // OLE2 compound document signature followed by garbage data. + // This simulates an encrypted or password-protected Office file. + ole2Sig := []byte{0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1} + garbage := make([]byte, 512) + for i := range garbage { + garbage[i] = byte(i % 256) + } + data := append(ole2Sig, garbage...) + return writeFile("encrypted.docx", data) +} + +func genSolidColorPNG() error { + // 100x100 solid white image (no variation). + img := image.NewNRGBA(image.Rect(0, 0, 100, 100)) + white := color.NRGBA{R: 255, G: 255, B: 255, A: 255} + for y := 0; y < 100; y++ { + for x := 0; x < 100; x++ { + img.SetNRGBA(x, y, white) + } + } + var buf bytes.Buffer + if err := png.Encode(&buf, img); err != nil { + return err + } + return writeFile("solid_color.png", buf.Bytes()) +} + +func genSmallJPEG() error { + // 10x10 JPEG -- too small for many document processing scenarios. + img := newTestImage(10, 10) + var buf bytes.Buffer + if err := jpeg.Encode(&buf, img, &jpeg.Options{Quality: 90}); err != nil { + return err + } + return writeFile("small.jpeg", buf.Bytes()) +} + +func genMacroDOCX() error { + // Valid DOCX structure with an extra word/vbaProject.bin entry, + // indicating the document contains macros. + return createZipFile("macro.docx", []zipEntry{ + { + Name: "[Content_Types].xml", + Body: ` + + + + + +`, + }, + { + Name: "_rels/.rels", + Body: ` + + +`, + }, + { + Name: "word/_rels/document.xml.rels", + Body: ` + + +`, + }, + { + Name: "word/document.xml", + Body: ` + + + + + Document with macros + + + +`, + }, + { + Name: "word/vbaProject.bin", + Body: "FAKE_VBA_PROJECT_BINARY_CONTENT", + }, + }) +} diff --git a/internal/document/types/testdata/multiformat/binary.txt b/internal/document/types/testdata/multiformat/binary.txt new file mode 100644 index 00000000..d6917c42 Binary files /dev/null and b/internal/document/types/testdata/multiformat/binary.txt differ diff --git a/internal/document/types/testdata/multiformat/empty.txt b/internal/document/types/testdata/multiformat/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/internal/document/types/testdata/multiformat/encrypted.docx b/internal/document/types/testdata/multiformat/encrypted.docx new file mode 100644 index 00000000..03a25faa Binary files /dev/null and b/internal/document/types/testdata/multiformat/encrypted.docx differ diff --git a/internal/document/types/testdata/multiformat/macro.docx b/internal/document/types/testdata/multiformat/macro.docx new file mode 100644 index 00000000..fd9b203a Binary files /dev/null and b/internal/document/types/testdata/multiformat/macro.docx differ diff --git a/internal/document/types/testdata/multiformat/small.jpeg b/internal/document/types/testdata/multiformat/small.jpeg new file mode 100644 index 00000000..27f0cbe6 Binary files /dev/null and b/internal/document/types/testdata/multiformat/small.jpeg differ diff --git a/internal/document/types/testdata/multiformat/solid_color.png b/internal/document/types/testdata/multiformat/solid_color.png new file mode 100644 index 00000000..f3258dc5 Binary files /dev/null and b/internal/document/types/testdata/multiformat/solid_color.png differ diff --git a/internal/document/types/testdata/multiformat/valid.bmp b/internal/document/types/testdata/multiformat/valid.bmp new file mode 100644 index 00000000..9ab06322 Binary files /dev/null and b/internal/document/types/testdata/multiformat/valid.bmp differ diff --git a/internal/document/types/testdata/multiformat/valid.docx b/internal/document/types/testdata/multiformat/valid.docx new file mode 100644 index 00000000..80c3b742 Binary files /dev/null and b/internal/document/types/testdata/multiformat/valid.docx differ diff --git a/internal/document/types/testdata/multiformat/valid.eml b/internal/document/types/testdata/multiformat/valid.eml new file mode 100644 index 00000000..a5059e10 --- /dev/null +++ b/internal/document/types/testdata/multiformat/valid.eml @@ -0,0 +1,7 @@ +From: sender@example.com +To: recipient@example.com +Subject: Test Email +Date: Mon, 01 Jan 2024 00:00:00 +0000 +Content-Type: text/plain; charset="utf-8" + +This is the body of the test email. diff --git a/internal/document/types/testdata/multiformat/valid.jpeg b/internal/document/types/testdata/multiformat/valid.jpeg new file mode 100644 index 00000000..8ab055a4 Binary files /dev/null and b/internal/document/types/testdata/multiformat/valid.jpeg differ diff --git a/internal/document/types/testdata/multiformat/valid.png b/internal/document/types/testdata/multiformat/valid.png new file mode 100644 index 00000000..e134f8b0 Binary files /dev/null and b/internal/document/types/testdata/multiformat/valid.png differ diff --git a/internal/document/types/testdata/multiformat/valid.pptx b/internal/document/types/testdata/multiformat/valid.pptx new file mode 100644 index 00000000..29c21544 Binary files /dev/null and b/internal/document/types/testdata/multiformat/valid.pptx differ diff --git a/internal/document/types/testdata/multiformat/valid.tiff b/internal/document/types/testdata/multiformat/valid.tiff new file mode 100644 index 00000000..8c1a5cf8 Binary files /dev/null and b/internal/document/types/testdata/multiformat/valid.tiff differ diff --git a/internal/document/types/testdata/multiformat/valid.txt b/internal/document/types/testdata/multiformat/valid.txt new file mode 100644 index 00000000..86d748f0 --- /dev/null +++ b/internal/document/types/testdata/multiformat/valid.txt @@ -0,0 +1,2 @@ +Hello, this is a test document. +It has multiple lines. diff --git a/internal/document/types/testdata/multiformat/valid.xlsx b/internal/document/types/testdata/multiformat/valid.xlsx new file mode 100644 index 00000000..850feefd Binary files /dev/null and b/internal/document/types/testdata/multiformat/valid.xlsx differ diff --git a/internal/document/types/testdata/multiformat/valid_utf16be.txt b/internal/document/types/testdata/multiformat/valid_utf16be.txt new file mode 100644 index 00000000..4ee6534f Binary files /dev/null and b/internal/document/types/testdata/multiformat/valid_utf16be.txt differ diff --git a/internal/document/types/testdata/multiformat/valid_utf16le.txt b/internal/document/types/testdata/multiformat/valid_utf16le.txt new file mode 100644 index 00000000..fe77fc3e Binary files /dev/null and b/internal/document/types/testdata/multiformat/valid_utf16le.txt differ diff --git a/internal/document/types/tiff.go b/internal/document/types/tiff.go new file mode 100644 index 00000000..7d1198e9 --- /dev/null +++ b/internal/document/types/tiff.go @@ -0,0 +1,183 @@ +package documenttypes + +import ( + "bytes" + "context" + "fmt" + "image/png" + "io" + "log/slog" + + "github.com/chai2010/tiff" +) + +// TIFF implements the File interface for TIFF image validation. +// It supports multi-frame TIFF files with DPI validation via IFD tags. +type TIFF struct { + data []byte +} + +// NewTIFFFromReader creates a new TIFF validator by reading all bytes from r. +func NewTIFFFromReader(r io.Reader) (*TIFF, error) { + data, err := io.ReadAll(r) + if err != nil { + return nil, err + } + return NewTIFF(data), nil +} + +// NewTIFF creates a new TIFF validator from raw file bytes. +func NewTIFF(data []byte) *TIFF { + return &TIFF{data: data} +} + +// IsCorrupt validates the TIFF file for corruption or unsupported content. +func (s *TIFF) IsCorrupt(_ context.Context) *InvalidDocumentReason { + if reason := s.checkMagicBytes(); reason != nil { + return reason + } + + reader, err := tiff.OpenReader(bytes.NewReader(s.data)) + if err != nil { + return invalidReason(InvalidDocumentRead) + } + defer reader.Close() + + frameCount := reader.ImageNum() + if frameCount < 1 { + return invalidReason(InvalidDocumentZeroPageCount) + } + + if len(s.data) > imageMaxFileSize { + return invalidReason(InvalidDocumentLargeFile) + } + + hasContent := false + for i := range frameCount { + if reason := s.validateFrame(reader, i); reason != nil { + return reason + } + + img, err := reader.DecodeImage(i, 0) + if err != nil { + slog.Debug("tiff: failed to decode frame", "index", i, "error", err) + return invalidReason(InvalidDocumentRead) + } + + if !hasContent && hasNonZeroPixelData(img) { + hasContent = true + } + } + + if !hasContent { + return invalidReason(InvalidDocumentEmptyContent) + } + + return nil +} + +// GetPageCount returns the number of IFD frames in the TIFF file. +func (s *TIFF) GetPageCount(_ context.Context) (int, error) { + reader, err := tiff.OpenReader(bytes.NewReader(s.data)) + if err != nil { + return 0, fmt.Errorf("tiff: failed to open reader: %w", err) + } + defer reader.Close() + + return reader.ImageNum(), nil +} + +// GetPage encodes the specified frame as PNG bytes. +func (s *TIFF) GetPage(_ context.Context, index int) ([]byte, error) { + reader, err := tiff.OpenReader(bytes.NewReader(s.data)) + if err != nil { + return nil, fmt.Errorf("tiff: failed to open reader: %w", err) + } + defer reader.Close() + + if index < 0 || index >= reader.ImageNum() { + return nil, fmt.Errorf("tiff: page index %d out of range [0, %d)", index, reader.ImageNum()) + } + + img, err := reader.DecodeImage(index, 0) + if err != nil { + return nil, fmt.Errorf("tiff: failed to decode frame %d: %w", index, err) + } + + var buf bytes.Buffer + if err := png.Encode(&buf, img); err != nil { + return nil, fmt.Errorf("tiff: failed to encode frame %d as PNG: %w", index, err) + } + + return buf.Bytes(), nil +} + +// checkMagicBytes verifies the TIFF file signature. +// Little-endian: 49 49 2A 00, Big-endian: 4D 4D 00 2A. +func (s *TIFF) checkMagicBytes() *InvalidDocumentReason { + if len(s.data) < 4 { + return invalidReason(InvalidDocumentMimeType) + } + + le := s.data[0] == 0x49 && s.data[1] == 0x49 && s.data[2] == 0x2A && s.data[3] == 0x00 + be := s.data[0] == 0x4D && s.data[1] == 0x4D && s.data[2] == 0x00 && s.data[3] == 0x2A + + if !le && !be { + return invalidReason(InvalidDocumentMimeType) + } + + return nil +} + +// validateFrame checks dimensions and DPI for a single TIFF frame. +func (s *TIFF) validateFrame(reader *tiff.Reader, frameIndex int) *InvalidDocumentReason { + cfg, err := reader.ImageConfig(frameIndex, 0) + if err != nil { + return invalidReason(InvalidDocumentRead) + } + + if reason := checkImageDimensions(cfg.Width, cfg.Height); reason != nil { + return reason + } + + return s.validateFrameDPI(reader, frameIndex) +} + +// validateFrameDPI reads XResolution/YResolution tags from the IFD entry +// and validates that DPI meets the minimum threshold. +// Defaults to 72 DPI if resolution tags are absent. +func (s *TIFF) validateFrameDPI(reader *tiff.Reader, frameIndex int) *InvalidDocumentReason { + if frameIndex >= len(reader.Ifd) || len(reader.Ifd[frameIndex]) == 0 { + return nil + } + + ifd := reader.Ifd[frameIndex][0] + tags := ifd.TagGetter() + + xDPI := float64(TEXTRACT_MIN_DPI) + yDPI := float64(TEXTRACT_MIN_DPI) + + resUnit, unitOK := tags.GetResolutionUnit() + + xRes, xOK := tags.GetXResolution() + if xOK && xRes[1] != 0 { + xDPI = float64(xRes[0]) / float64(xRes[1]) + if unitOK && resUnit == tiff.TagValue_ResolutionUnitType_PerCM { + xDPI *= 2.54 + } + } + + yRes, yOK := tags.GetYResolution() + if yOK && yRes[1] != 0 { + yDPI = float64(yRes[0]) / float64(yRes[1]) + if unitOK && resUnit == tiff.TagValue_ResolutionUnitType_PerCM { + yDPI *= 2.54 + } + } + + if xDPI < float64(TEXTRACT_MIN_DPI) || yDPI < float64(TEXTRACT_MIN_DPI) { + return invalidReason(InvalidDocumentSmallDPI) + } + + return nil +} diff --git a/internal/document/types/tiff_test.go b/internal/document/types/tiff_test.go new file mode 100644 index 00000000..bee72f13 --- /dev/null +++ b/internal/document/types/tiff_test.go @@ -0,0 +1,74 @@ +package documenttypes + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestTIFF_ValidFile(t *testing.T) { + data, err := os.ReadFile("testdata/multiformat/valid.tiff") + require.NoError(t, err) + + tif := NewTIFF(data) + ctx := t.Context() + + t.Run("IsCorrupt returns nil", func(t *testing.T) { + reason := tif.IsCorrupt(ctx) + assert.Nil(t, reason) + }) + + t.Run("GetPageCount >= 1", func(t *testing.T) { + count, err := tif.GetPageCount(ctx) + require.NoError(t, err) + assert.GreaterOrEqual(t, count, 1) + }) + + t.Run("GetPage(0) returns data", func(t *testing.T) { + page, err := tif.GetPage(ctx, 0) + require.NoError(t, err) + assert.NotEmpty(t, page) + }) +} + +func TestTIFF_InvalidMagicBytes(t *testing.T) { + // Raw bytes that are not a valid TIFF signature. + data := []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07} + tif := NewTIFF(data) + + reason := tif.IsCorrupt(t.Context()) + require.NotNil(t, reason) + assert.Equal(t, InvalidDocumentMimeType, *reason) +} + +func TestTIFF_TooShort(t *testing.T) { + // Less than 4 bytes -- cannot contain a valid TIFF header. + data := []byte{0x49, 0x49} + tif := NewTIFF(data) + + reason := tif.IsCorrupt(t.Context()) + require.NotNil(t, reason) + assert.Equal(t, InvalidDocumentMimeType, *reason) +} + +func TestTIFF_CorruptData(t *testing.T) { + // Valid little-endian TIFF magic bytes followed by garbage. + data := make([]byte, 128) + data[0] = 0x49 + data[1] = 0x49 + data[2] = 0x2A + data[3] = 0x00 + // Remainder is zeros/garbage -- the IFD offset is invalid. + + tif := NewTIFF(data) + reason := tif.IsCorrupt(t.Context()) + require.NotNil(t, reason) + assert.Equal(t, InvalidDocumentRead, *reason) +} + +func TestTIFF_LargeFileSize(t *testing.T) { + // Verify the imageMaxFileSize constant exists and has the expected value. + assert.Equal(t, 500*1024*1024, imageMaxFileSize) +} diff --git a/internal/document/types/txt.go b/internal/document/types/txt.go new file mode 100644 index 00000000..022c6b2a --- /dev/null +++ b/internal/document/types/txt.go @@ -0,0 +1,245 @@ +package documenttypes + +import ( + "bytes" + "context" + "fmt" + "io" + "strings" + + "github.com/dimchansky/utfbom" + "github.com/saintfish/chardet" + "golang.org/x/text/encoding/charmap" + "golang.org/x/text/encoding/unicode" + "golang.org/x/text/transform" +) + +const ( + // maxTXTFileSize is the maximum allowed file size for plain text files (100MB). + maxTXTFileSize = 100 * 1024 * 1024 + // binaryCheckSize is the number of bytes to scan for null bytes and binary signatures. + binaryCheckSize = 8192 + // signatureCheckSize is the number of bytes to check for binary file signatures. + signatureCheckSize = 8 +) + +// TXT implements the File interface for plain text document validation. +// It checks for binary content, encoding, and file size constraints. +type TXT struct { + data []byte +} + +// NewTXT creates a new TXT validator from raw file bytes. +func NewTXT(data []byte) *TXT { + return &TXT{data: data} +} + +// IsCorrupt validates the plain text file for corruption or unsupported content. +// It checks binary signatures, null bytes, file size, encoding, and empty content. +func (s *TXT) IsCorrupt(_ context.Context) *InvalidDocumentReason { + if reason := s.checkBinarySignatures(); reason != nil { + return reason + } + + if reason := s.checkNullBytes(); reason != nil { + return reason + } + + if reason := s.checkFileSize(); reason != nil { + return reason + } + + decoded, reason := s.decodeToUTF8() + if reason != nil { + return reason + } + + if strings.TrimSpace(string(decoded)) == "" { + r := InvalidDocumentEmptyContent + return &r + } + + return nil +} + +// GetPageCount returns the number of pages. Plain text is always 1 page. +func (s *TXT) GetPageCount(_ context.Context) (int, error) { + return 1, nil +} + +// GetPage returns the file content decoded to UTF-8. Only page index 0 is valid. +func (s *TXT) GetPage(_ context.Context, index int) ([]byte, error) { + if index != 0 { + return nil, fmt.Errorf("invalid page index %d: TXT files have exactly 1 page", index) + } + + decoded, reason := s.decodeToUTF8() + if reason != nil { + return nil, fmt.Errorf("failed to decode TXT content: %s", *reason) + } + + return decoded, nil +} + +// checkBinarySignatures tests the first bytes of the file against known binary format +// signatures. Returns InvalidDocumentMimeType if the file matches a binary format. +func (s *TXT) checkBinarySignatures() *InvalidDocumentReason { + if len(s.data) < 2 { + return nil + } + + header := s.data + if len(header) > signatureCheckSize { + header = header[:signatureCheckSize] + } + + // Known binary file signatures to reject. + signatures := [][]byte{ + {0x25, 0x50, 0x44, 0x46, 0x2D}, // PDF: %PDF- + {0x50, 0x4B, 0x03, 0x04}, // ZIP (DOCX/XLSX/PPTX) + {0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}, // OLE2 (DOC/XLS/PPT) + {0x49, 0x49, 0x2A, 0x00}, // TIFF little-endian + {0x4D, 0x4D, 0x00, 0x2A}, // TIFF big-endian + {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A}, // PNG + {0xFF, 0xD8, 0xFF}, // JPEG + {0x42, 0x4D}, // BMP + } + + for _, sig := range signatures { + if len(header) >= len(sig) && bytes.Equal(header[:len(sig)], sig) { + r := InvalidDocumentMimeType + return &r + } + } + + return nil +} + +// checkNullBytes scans the first binaryCheckSize bytes for null bytes (0x00), +// which indicate binary content. Returns InvalidDocumentBinaryContent if found. +// UTF-16 files with BOM are exempt -- null bytes are expected in their encoding. +func (s *TXT) checkNullBytes() *InvalidDocumentReason { + if s.hasUTF16BOM() { + return nil + } + + scanLen := min(len(s.data), binaryCheckSize) + + for i := range scanLen { + if s.data[i] == 0x00 { + r := InvalidDocumentBinaryContent + return &r + } + } + + return nil +} + +// hasUTF16BOM returns true if the data starts with a UTF-16 LE or BE byte order mark. +func (s *TXT) hasUTF16BOM() bool { + if len(s.data) < 2 { + return false + } + // UTF-16LE BOM: FF FE + if s.data[0] == 0xFF && s.data[1] == 0xFE { + return true + } + // UTF-16BE BOM: FE FF + if s.data[0] == 0xFE && s.data[1] == 0xFF { + return true + } + return false +} + +// checkFileSize validates the file is not empty and not larger than maxTXTFileSize. +func (s *TXT) checkFileSize() *InvalidDocumentReason { + if len(s.data) == 0 { + r := InvalidDocumentEmptyContent + return &r + } + + if len(s.data) > maxTXTFileSize { + r := InvalidDocumentLargeFile + return &r + } + + return nil +} + +// decodeToUTF8 detects the encoding of the file data and decodes it to UTF-8. +// It tries BOM detection first, then falls back to heuristic charset detection. +// Returns the decoded bytes and nil on success, or nil and an InvalidDocumentReason on failure. +func (s *TXT) decodeToUTF8() ([]byte, *InvalidDocumentReason) { + // Step 1: Try BOM detection using utfbom.Skip which returns encoding info. + bomReader, encoding := utfbom.Skip(bytes.NewReader(s.data)) + + switch encoding { + case utfbom.UTF8: + // UTF-8 with BOM -- read the data past the BOM. + data, err := io.ReadAll(bomReader) + if err != nil { + r := InvalidDocumentRead + return nil, &r + } + return data, nil + + case utfbom.UTF16BigEndian: + // Re-read from original data so the UTF-16 decoder can see the BOM. + decoder := unicode.UTF16(unicode.BigEndian, unicode.ExpectBOM).NewDecoder() + decoded, err := io.ReadAll(transform.NewReader(bytes.NewReader(s.data), decoder)) + if err != nil { + r := InvalidDocumentUnsupportedEncoding + return nil, &r + } + return decoded, nil + + case utfbom.UTF16LittleEndian: + decoder := unicode.UTF16(unicode.LittleEndian, unicode.ExpectBOM).NewDecoder() + decoded, err := io.ReadAll(transform.NewReader(bytes.NewReader(s.data), decoder)) + if err != nil { + r := InvalidDocumentUnsupportedEncoding + return nil, &r + } + return decoded, nil + + case utfbom.Unknown: + // No BOM found -- fall through to heuristic detection. + } + + // Step 2: Heuristic charset detection for BOM-less files. + detector := chardet.NewTextDetector() + result, err := detector.DetectBest(s.data) + if err != nil || result == nil { + r := InvalidDocumentUnsupportedEncoding + return nil, &r + } + + charset := strings.ToUpper(result.Charset) + + switch charset { + case "UTF-8", "ASCII": + return s.data, nil + + case "ISO-8859-1": + decoded, decErr := io.ReadAll(transform.NewReader( + bytes.NewReader(s.data), charmap.ISO8859_1.NewDecoder())) + if decErr != nil { + r := InvalidDocumentUnsupportedEncoding + return nil, &r + } + return decoded, nil + + case "WINDOWS-1252": + decoded, decErr := io.ReadAll(transform.NewReader( + bytes.NewReader(s.data), charmap.Windows1252.NewDecoder())) + if decErr != nil { + r := InvalidDocumentUnsupportedEncoding + return nil, &r + } + return decoded, nil + + default: + r := InvalidDocumentUnsupportedEncoding + return nil, &r + } +} diff --git a/internal/document/types/txt_test.go b/internal/document/types/txt_test.go new file mode 100644 index 00000000..0c3a424d --- /dev/null +++ b/internal/document/types/txt_test.go @@ -0,0 +1,173 @@ +package documenttypes + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestTXT_ValidFile(t *testing.T) { + ctx := t.Context() + data, err := os.ReadFile("testdata/multiformat/valid.txt") + require.NoError(t, err) + + txt := NewTXT(data) + + t.Run("IsCorrupt returns nil", func(t *testing.T) { + reason := txt.IsCorrupt(ctx) + assert.Nil(t, reason) + }) + + t.Run("GetPageCount returns 1", func(t *testing.T) { + count, err := txt.GetPageCount(ctx) + require.NoError(t, err) + assert.Equal(t, 1, count) + }) + + t.Run("GetPage returns content", func(t *testing.T) { + page, err := txt.GetPage(ctx, 0) + require.NoError(t, err) + assert.NotNil(t, page) + assert.Contains(t, string(page), "Hello, this is a test document.") + }) +} + +func TestTXT_EmptyFile(t *testing.T) { + ctx := t.Context() + data, err := os.ReadFile("testdata/multiformat/empty.txt") + require.NoError(t, err) + + txt := NewTXT(data) + reason := txt.IsCorrupt(ctx) + require.NotNil(t, reason) + assert.Equal(t, InvalidDocumentEmptyContent, *reason) +} + +func TestTXT_BinaryContent(t *testing.T) { + ctx := t.Context() + data, err := os.ReadFile("testdata/multiformat/binary.txt") + require.NoError(t, err) + + txt := NewTXT(data) + reason := txt.IsCorrupt(ctx) + require.NotNil(t, reason) + assert.Equal(t, InvalidDocumentBinaryContent, *reason) +} + +func TestTXT_BinarySignature(t *testing.T) { + ctx := t.Context() + // PDF magic bytes: %PDF- + data := []byte{0x25, 0x50, 0x44, 0x46, 0x2D, 0x31, 0x2E, 0x34} + + txt := NewTXT(data) + reason := txt.IsCorrupt(ctx) + require.NotNil(t, reason) + assert.Equal(t, InvalidDocumentMimeType, *reason) +} + +func TestTXT_WhitespaceOnly(t *testing.T) { + ctx := t.Context() + data := []byte(" \n\t\n \n") + + txt := NewTXT(data) + reason := txt.IsCorrupt(ctx) + require.NotNil(t, reason) + assert.Equal(t, InvalidDocumentEmptyContent, *reason) +} + +func TestTXT_LargeFile(t *testing.T) { + ctx := t.Context() + // Verify the constant value rather than allocating 100MB+. + // maxTXTFileSize is 100 * 1024 * 1024 = 104857600. + // Create a TXT with a data length that just exceeds the limit via a + // slice header trick: we only need checkFileSize to see len(data) > maxTXTFileSize. + // Since we cannot avoid allocation entirely (the struct holds []byte), we create + // a minimal slice that reports the right length by extending a small backing array. + // + // Actually the simplest approach: create a byte slice of length maxTXTFileSize+1. + // To avoid 100MB allocation in tests, we test the checkFileSize method directly + // with a struct whose data field is set to a large-length slice. + // Go slices from make() are zero-initialized but not physically allocated until touched. + // However, the null-byte check scans up to 8192 bytes, so the first 8192 bytes will be + // null and trigger InvalidDocumentBinaryContent before reaching the size check. + // + // Instead, let's test the checkFileSize method directly. + largeSize := maxTXTFileSize + 1 + txt := &TXT{data: make([]byte, largeSize)} + reason := txt.checkFileSize() + require.NotNil(t, reason) + assert.Equal(t, InvalidDocumentLargeFile, *reason) + + // Also verify that a file at exactly the limit passes the size check. + txt2 := &TXT{data: make([]byte, maxTXTFileSize)} + reason2 := txt2.checkFileSize() + assert.Nil(t, reason2) + + // Verify via IsCorrupt that the large file is caught (it will hit binary check first + // due to zero bytes, so we verify the size check independently above). + reason3 := txt.IsCorrupt(ctx) + require.NotNil(t, reason3, "large file with zero bytes should be detected as invalid") +} + +func TestTXT_UTF8Content(t *testing.T) { + ctx := t.Context() + data := []byte("This is plain ASCII and UTF-8 compatible text.\nLine two.") + + txt := NewTXT(data) + reason := txt.IsCorrupt(ctx) + assert.Nil(t, reason) + + page, err := txt.GetPage(ctx, 0) + require.NoError(t, err) + assert.Equal(t, string(data), string(page)) +} + +func TestTXT_UTF16LE_WithBOM(t *testing.T) { + ctx := t.Context() + data, err := os.ReadFile("testdata/multiformat/valid_utf16le.txt") + require.NoError(t, err) + + txt := NewTXT(data) + + t.Run("IsCorrupt returns nil", func(t *testing.T) { + reason := txt.IsCorrupt(ctx) + assert.Nil(t, reason, "UTF-16LE file with BOM should be valid") + }) + + t.Run("GetPage returns decoded content", func(t *testing.T) { + page, err := txt.GetPage(ctx, 0) + require.NoError(t, err) + assert.Contains(t, string(page), "Hello") + }) +} + +func TestTXT_UTF16BE_WithBOM(t *testing.T) { + ctx := t.Context() + data, err := os.ReadFile("testdata/multiformat/valid_utf16be.txt") + require.NoError(t, err) + + txt := NewTXT(data) + + t.Run("IsCorrupt returns nil", func(t *testing.T) { + reason := txt.IsCorrupt(ctx) + assert.Nil(t, reason, "UTF-16BE file with BOM should be valid") + }) + + t.Run("GetPage returns decoded content", func(t *testing.T) { + page, err := txt.GetPage(ctx, 0) + require.NoError(t, err) + assert.Contains(t, string(page), "Hello") + }) +} + +func TestTXT_GetPageInvalidIndex(t *testing.T) { + ctx := t.Context() + data := []byte("Hello") + txt := NewTXT(data) + + _, err := txt.GetPage(ctx, 1) + require.Error(t, err) + assert.Contains(t, err.Error(), "invalid page index") +} diff --git a/internal/document/types/xlsx.go b/internal/document/types/xlsx.go new file mode 100644 index 00000000..41f934dd --- /dev/null +++ b/internal/document/types/xlsx.go @@ -0,0 +1,275 @@ +package documenttypes + +import ( + "archive/zip" + "context" + "encoding/xml" + "strings" +) + +// XLSX represents an Excel OOXML spreadsheet for validation and sheet extraction. +type XLSX struct { + data []byte +} + +// NewXLSX creates a new XLSX validator from raw file data. +func NewXLSX(data []byte) *XLSX { + return &XLSX{data: data} +} + +// xlsxWorkbook is a minimal XML representation of xl/workbook.xml, +// capturing sheets and file sharing (password) info. +type xlsxWorkbook struct { + XMLName xml.Name `xml:"workbook"` + Sheets xlsxSheets `xml:"sheets"` + FileSharing *xlsxFileSharing `xml:"fileSharing"` +} + +type xlsxSheets struct { + Sheet []xlsxSheet `xml:"sheet"` +} + +type xlsxSheet struct { + Name string `xml:"name,attr"` +} + +type xlsxFileSharing struct { + Password string `xml:"password,attr"` + HashValue string `xml:"hashValue,attr"` + ReservationPassword string `xml:"reservationPassword,attr"` +} + +// xlsxSheetData is a minimal XML representation of a worksheet, +// capturing rows and cells to detect content. +type xlsxSheetData struct { + XMLName xml.Name `xml:"worksheet"` + Rows []xlsxRow `xml:"sheetData>row"` +} + +type xlsxRow struct { + Cells []xlsxCell `xml:"c"` +} + +type xlsxCell struct { + Value string `xml:"v"` +} + +// xlsxSharedStrings is a minimal representation of xl/sharedStrings.xml. +type xlsxSharedStrings struct { + XMLName xml.Name `xml:"sst"` + Items []xlsxSSItem `xml:"si"` +} + +type xlsxSSItem struct { + Text string `xml:"t"` +} + +// IsCorrupt validates the XLSX document, returning the reason it is invalid +// or nil if the document passes all checks. +func (s *XLSX) IsCorrupt(_ context.Context) *InvalidDocumentReason { + // 1. Check for OLE2 encryption (encrypted OOXML files use OLE2 wrapper) + if IsOLE2Encrypted(s.data) { + reason := InvalidDocumentPasswordProtected + return &reason + } + + // 2. Check ZIP signature + if !hasZIPSignature(s.data) { + reason := InvalidDocumentMimeType + return &reason + } + + // 3. Open ZIP and verify content type + zr, err := openOfficeZIP(s.data) + if err != nil { + reason := InvalidDocumentMimeType + return &reason + } + + ct, err := readZIPFile(zr, "[Content_Types].xml") + if err != nil || !strings.Contains(string(ct), "spreadsheetml.sheet.main+xml") { + reason := InvalidDocumentMimeType + return &reason + } + + // 4. Reject if macros are present + if hasVBAMacros(zr) { + reason := InvalidDocumentContainsMacros + return &reason + } + if r := s.hasPasswordProtection(zr); r != nil { + return r + } + + // 5. Verify workbook and at least one sheet exist and parse + if r := s.validateStructure(zr); r != nil { + return r + } + + // 6. File size check + if len(s.data) > officeMaxFileSize { + reason := InvalidDocumentLargeFile + return &reason + } + + // 7. Content check + if !s.hasContent(zr) { + reason := InvalidDocumentEmptyContent + return &reason + } + + // 8. Sheet count check + sheetCount, countErr := s.sheetCount(zr) + if countErr != nil || sheetCount < 1 { + reason := InvalidDocumentZeroPageCount + return &reason + } + + return nil +} + +// GetPageCount returns the number of sheets in the workbook. +func (s *XLSX) GetPageCount(_ context.Context) (int, error) { + zr, err := openOfficeZIP(s.data) + if err != nil { + return 0, err + } + + count, err := s.sheetCount(zr) + if err != nil { + return 0, err + } + + if count < 1 { + count = 1 + } + return count, nil +} + +// GetPage returns the raw spreadsheet bytes for the requested page index. +func (s *XLSX) GetPage(_ context.Context, _ int) ([]byte, error) { + return s.data, nil +} + +// hasPasswordProtection checks xl/workbook.xml for fileSharing elements +// with password hashes indicating protection. +func (s *XLSX) hasPasswordProtection(zr *zip.Reader) *InvalidDocumentReason { + wbXML, err := readZIPFile(zr, "xl/workbook.xml") + if err != nil { + return nil + } + + var wb xlsxWorkbook + if xmlErr := xml.Unmarshal(wbXML, &wb); xmlErr != nil { + return nil + } + + if wb.FileSharing != nil && + (wb.FileSharing.Password != "" || + wb.FileSharing.HashValue != "" || + wb.FileSharing.ReservationPassword != "") { + reason := InvalidDocumentPasswordProtected + return &reason + } + + return nil +} + +// validateStructure verifies that xl/workbook.xml and at least one +// xl/worksheets/sheet*.xml exist and parse as valid XML. +func (s *XLSX) validateStructure(zr *zip.Reader) *InvalidDocumentReason { + wbXML, err := readZIPFile(zr, "xl/workbook.xml") + if err != nil { + reason := InvalidDocumentRead + return &reason + } + + var wb xlsxWorkbook + if xmlErr := xml.Unmarshal(wbXML, &wb); xmlErr != nil { + reason := InvalidDocumentRead + return &reason + } + + // Check at least one worksheet file exists + hasSheet := false + for _, f := range zr.File { + if strings.HasPrefix(f.Name, "xl/worksheets/sheet") && + strings.HasSuffix(f.Name, ".xml") { + hasSheet = true + break + } + } + if !hasSheet { + reason := InvalidDocumentRead + return &reason + } + + return nil +} + +// hasContent checks whether any sheet has a row with a cell containing a +// non-empty value, or if shared strings has entries. +func (s *XLSX) hasContent(zr *zip.Reader) bool { + // Check shared strings first (faster for large spreadsheets) + if s.hasSharedStrings(zr) { + return true + } + + // Check individual sheets for cell values + for _, f := range zr.File { + if !strings.HasPrefix(f.Name, "xl/worksheets/sheet") || + !strings.HasSuffix(f.Name, ".xml") { + continue + } + + sheetXML, err := readZIPFile(zr, f.Name) + if err != nil { + continue + } + + var sheet xlsxSheetData + if xmlErr := xml.Unmarshal(sheetXML, &sheet); xmlErr != nil { + continue + } + + for _, row := range sheet.Rows { + for _, cell := range row.Cells { + if strings.TrimSpace(cell.Value) != "" { + return true + } + } + } + } + + return false +} + +// hasSharedStrings checks if xl/sharedStrings.xml has any entries. +func (s *XLSX) hasSharedStrings(zr *zip.Reader) bool { + ssXML, err := readZIPFile(zr, "xl/sharedStrings.xml") + if err != nil { + return false + } + + var ss xlsxSharedStrings + if xmlErr := xml.Unmarshal(ssXML, &ss); xmlErr != nil { + return false + } + + return len(ss.Items) > 0 +} + +// sheetCount returns the number of sheets defined in the workbook. +func (s *XLSX) sheetCount(zr *zip.Reader) (int, error) { + wbXML, err := readZIPFile(zr, "xl/workbook.xml") + if err != nil { + return 0, err + } + + var wb xlsxWorkbook + if xmlErr := xml.Unmarshal(wbXML, &wb); xmlErr != nil { + return 0, xmlErr + } + + return len(wb.Sheets.Sheet), nil +} diff --git a/internal/document/types/xlsx_test.go b/internal/document/types/xlsx_test.go new file mode 100644 index 00000000..1162aa1c --- /dev/null +++ b/internal/document/types/xlsx_test.go @@ -0,0 +1,61 @@ +package documenttypes + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestXLSX_ValidFile(t *testing.T) { + ctx := t.Context() + data, err := os.ReadFile("testdata/multiformat/valid.xlsx") + require.NoError(t, err) + + xlsx := NewXLSX(data) + + t.Run("IsCorrupt returns nil", func(t *testing.T) { + reason := xlsx.IsCorrupt(ctx) + assert.Nil(t, reason, "valid.xlsx should not be corrupt") + }) + + t.Run("GetPageCount >= 1", func(t *testing.T) { + count, err := xlsx.GetPageCount(ctx) + require.NoError(t, err) + assert.GreaterOrEqual(t, count, 1) + }) + + t.Run("GetPage returns data", func(t *testing.T) { + page, err := xlsx.GetPage(ctx, 0) + require.NoError(t, err) + assert.NotEmpty(t, page) + }) +} + +func TestXLSX_InvalidMagicBytes(t *testing.T) { + ctx := t.Context() + data := []byte("this is not a ZIP or XLSX file") + + xlsx := NewXLSX(data) + reason := xlsx.IsCorrupt(ctx) + + require.NotNil(t, reason) + assert.Equal(t, InvalidDocumentMimeType, *reason) +} + +func TestXLSX_Encrypted(t *testing.T) { + // encrypted.docx has the OLE2 signature but is not a parseable OLE2 compound + // document (malformed fixture). IsOLE2Encrypted returns false, then the ZIP + // signature check fails, so it returns InvalidDocumentMimeType. + ctx := t.Context() + data, err := os.ReadFile("testdata/multiformat/encrypted.docx") + require.NoError(t, err) + + xlsx := NewXLSX(data) + reason := xlsx.IsCorrupt(ctx) + + require.NotNil(t, reason) + assert.Equal(t, InvalidDocumentMimeType, *reason, + "malformed OLE2 file should fail ZIP signature check") +} diff --git a/internal/document/upload/get.go b/internal/document/upload/get.go index 7152d424..c95ca907 100644 --- a/internal/document/upload/get.go +++ b/internal/document/upload/get.go @@ -213,6 +213,9 @@ func (s *Service) UploadWithResult(ctx context.Context, file File) (UploadResult Part: &newPart, BatchID: file.BatchID, } + if ext := strings.TrimPrefix(filepath.Ext(filename), "."); ext != "" { + result.Key.FileType = &ext + } keyStr := result.Key.String() bucket := s.cfg.GetBucket() diff --git a/internal/document/upload/get_test.go b/internal/document/upload/get_test.go index 3f13a48b..bfc9cf27 100644 --- a/internal/document/upload/get_test.go +++ b/internal/document/upload/get_test.go @@ -214,3 +214,68 @@ func TestUploadAndReturnKey(t *testing.T) { assert.Equal(t, "client_id", key.ClientID) assert.NotEmpty(t, key.String()) } + +// TestUpload_SetsFileTypeOnKey verifies that UploadWithResult sets the FileType +// field on the BucketKey based on the filename extension. +func TestUpload_SetsFileTypeOnKey(t *testing.T) { + t.Parallel() + cfg := &Config{} + test.CreateDB(t, cfg) + acfg := test.CreateAWSContainer(t, cfg) + test.SetStoreClient(t, t.Context(), cfg, acfg.ExternalEndpoint) + test.CreateBucket(t, cfg) + createTestClient(t, cfg, "client_id", "client") + + svc := documentupload.New(cfg) + + tests := []struct { + name string + filename string + wantFileType *string + }{ + { + name: "pdf extension", + filename: "test.pdf", + wantFileType: strPtr("pdf"), + }, + { + name: "txt extension", + filename: "notes.txt", + wantFileType: strPtr("txt"), + }, + { + name: "docx extension", + filename: "report.docx", + wantFileType: strPtr("docx"), + }, + { + name: "no extension", + filename: "noext", + wantFileType: nil, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + file := documentupload.File{ + ClientID: "client_id", + Content: strings.NewReader("file content"), + Filename: tt.filename, + } + + result, err := svc.UploadWithResult(t.Context(), file) + require.NoError(t, err) + + if tt.wantFileType == nil { + assert.Nil(t, result.Key.FileType, "FileType should be nil for filename without extension") + } else { + require.NotNil(t, result.Key.FileType, "FileType should not be nil for filename with extension") + assert.Equal(t, *tt.wantFileType, *result.Key.FileType) + } + }) + } +} + +func strPtr(s string) *string { + return &s +} diff --git a/internal/server/api/batch_worker.go b/internal/server/api/batch_worker.go index 131ff21a..54c078df 100644 --- a/internal/server/api/batch_worker.go +++ b/internal/server/api/batch_worker.go @@ -28,6 +28,30 @@ const ( ConfigKeyUploadHandler = "uploadHandler" ) +// acceptedExtensions defines the file extensions allowed in batch uploads. +// Macro-enabled extensions (.docm, .xlsm, .pptm) are intentionally excluded -- +// documents with macros are rejected, so users must save as standard formats first. +var acceptedExtensions = map[string]bool{ + ".pdf": true, + ".tiff": true, + ".tif": true, + ".jpeg": true, + ".jpg": true, + ".png": true, + ".bmp": true, + ".docx": true, + ".xlsx": true, + ".pptx": true, + ".txt": true, + ".eml": true, +} + +// isAcceptedExtension checks if a filename has a supported file extension. +func isAcceptedExtension(filename string) bool { + ext := strings.ToLower(path.Ext(filename)) + return acceptedExtensions[ext] +} + // sanitizeZipPath cleans a path from a zip file to prevent path traversal attacks // while preserving the internal folder structure. // Returns empty string if the path is invalid or attempts traversal. @@ -194,6 +218,12 @@ func processSingleBatch( invalidInt32 = maxInt32 // Max int32 value } + // Set total document count now that all files have been extracted + totalInt32 := processedInt32 + failedInt32 + invalidInt32 + if err := batchService.SetTotalDocuments(ctx, batchInfo.ID, totalInt32); err != nil { + logger.Error("Failed to set batch total documents", "batch_id", batchInfo.ID, "error", err) + } + if err := batchService.UpdateProgress(ctx, batchInfo.ClientID, batchInfo.ID, processedInt32, failedInt32, invalidInt32); err != nil { logger.Error("Failed to update batch progress", "batch_id", batchInfo.ID, "error", err) @@ -320,8 +350,8 @@ func processZipFile( return 0, 1, 0 } - // Check if file type is valid (PDF only for now) - if !strings.HasSuffix(strings.ToLower(filename), ".pdf") { + // Check if file type is supported + if !isAcceptedExtension(filename) { logger.Warn("Invalid file type", "filename", filename) _ = batchService.AddFailedFilename(ctx, batchInfo.ID, filename) _ = batchService.RecordOutcome(ctx, batchInfo.ID, filename, repository.BatchOutcomeStatusInvalidType, nil, nil) diff --git a/internal/server/api/batch_worker_extension_test.go b/internal/server/api/batch_worker_extension_test.go new file mode 100644 index 00000000..f7aca326 --- /dev/null +++ b/internal/server/api/batch_worker_extension_test.go @@ -0,0 +1,95 @@ +package api + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestIsAcceptedExtension_AllSupported(t *testing.T) { + supported := []string{ + ".pdf", ".tiff", ".tif", ".jpeg", ".jpg", + ".png", ".bmp", ".docx", ".xlsx", + ".pptx", ".txt", ".eml", + } + + for _, ext := range supported { + t.Run(ext, func(t *testing.T) { + assert.True(t, isAcceptedExtension("document"+ext), + "expected %s to be accepted", ext) + }) + } +} + +func TestIsAcceptedExtension_CaseInsensitive(t *testing.T) { + cases := []struct { + filename string + }{ + {"report.PDF"}, + {"image.Png"}, + {"file.DOCX"}, + {"scan.TiFf"}, + {"mail.EML"}, + } + + for _, tc := range cases { + t.Run(tc.filename, func(t *testing.T) { + assert.True(t, isAcceptedExtension(tc.filename), + "expected %s to be accepted (case insensitive)", tc.filename) + }) + } +} + +func TestIsAcceptedExtension_Unsupported(t *testing.T) { + unsupported := []struct { + filename string + }{ + {"virus.exe"}, + {"library.dll"}, + {"outlook.msg"}, + {"legacy.doc"}, + {"old.xls"}, + {"slides.ppt"}, + {"archive.zip"}, + {"data.csv"}, + {"page.html"}, + {"macros.docm"}, + {"macros.xlsm"}, + {"macros.pptm"}, + } + + for _, tc := range unsupported { + t.Run(tc.filename, func(t *testing.T) { + assert.False(t, isAcceptedExtension(tc.filename), + "expected %s to be rejected", tc.filename) + }) + } +} + +func TestIsAcceptedExtension_NoExtension(t *testing.T) { + assert.False(t, isAcceptedExtension("README"), + "file with no extension should be rejected") + assert.False(t, isAcceptedExtension("Makefile"), + "file with no extension should be rejected") +} + +func TestIsAcceptedExtension_WithPath(t *testing.T) { + cases := []struct { + name string + filename string + want bool + }{ + {"nested pdf", "folder/document.pdf", true}, + {"deep path docx", "a/b/c/report.docx", true}, + {"nested unsupported", "folder/file.exe", false}, + {"path with spaces", "my folder/scan.png", true}, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + got := isAcceptedExtension(tc.filename) + assert.Equal(t, tc.want, got, + "isAcceptedExtension(%q) = %v, want %v", tc.filename, got, tc.want) + }) + } +} diff --git a/internal/server/api/batch_worker_test.go b/internal/server/api/batch_worker_test.go index cfc15c89..656374db 100644 --- a/internal/server/api/batch_worker_test.go +++ b/internal/server/api/batch_worker_test.go @@ -59,8 +59,9 @@ func TestProcessBatchWork(t *testing.T) { }) require.NoError(t, err) - // Create a batch record in the database - batchID, err := batchService.CreateWithStorage(ctx, clientID, "batch.zip", 2, bucket, archiveKey, int64(len(zipContent))) + // Create a batch record with totalDocs=0 to match production (documents.go:236). + // The worker must call SetTotalDocuments after extraction for progress to work. + batchID, err := batchService.CreateWithStorage(ctx, clientID, "batch.zip", 0, bucket, archiveKey, int64(len(zipContent))) require.NoError(t, err) // Track uploaded documents @@ -96,8 +97,17 @@ func TestProcessBatchWork(t *testing.T) { batchInfo, err := batchService.Get(ctx, clientID, batchID) require.NoError(t, err) assert.Equal(t, "completed", batchInfo.Status) - assert.Equal(t, int32(2), batchInfo.ProcessedDocuments) - assert.Equal(t, int32(0), batchInfo.FailedDocuments) + assert.Equal(t, int32(2), batchInfo.TotalDocuments, "TotalDocuments should be set after processing") + + // Summary counts are derived from outcome states. After extraction, outcomes + // are in 'submitted' (non-terminal) state -- pipeline hasn't run yet. + // Only terminal outcomes (clean_passed, clean_failed, etc.) are counted. + outcomes, err := batchService.ListOutcomes(ctx, batchID) + require.NoError(t, err) + assert.Len(t, outcomes, 2, "should have 2 outcome rows") + for _, o := range outcomes { + assert.Equal(t, "submitted", o.Outcome) + } } // TestProcessSingleBatch tests processing a single batch @@ -162,14 +172,23 @@ func TestProcessSingleBatch(t *testing.T) { err = processSingleBatch(ctx, logger, batchService, s3Client, bucket, uploadHandler, batchDetails) require.NoError(t, err) - // Verify only PDFs were uploaded - assert.Equal(t, 1, uploadCount) // Only 1 PDF file + // All three file types (PDF, TXT, DOCX) are now accepted + assert.Equal(t, 3, uploadCount) // Verify batch status batchInfo, err := batchService.Get(ctx, clientID, batchID) require.NoError(t, err) - assert.Equal(t, int32(1), batchInfo.ProcessedDocuments) - assert.Equal(t, int32(2), batchInfo.InvalidTypeDocuments) // 1 txt + 1 docx + assert.Equal(t, "completed", batchInfo.Status) + assert.Equal(t, int32(3), batchInfo.TotalDocuments) + + // After extraction, outcomes are 'submitted' (non-terminal). + // Derived counts only reflect terminal outcomes. + outcomes, err := batchService.ListOutcomes(ctx, batchID) + require.NoError(t, err) + assert.Len(t, outcomes, 3) + for _, o := range outcomes { + assert.Equal(t, "submitted", o.Outcome) + } } // TestProcessSingleBatchWithFailure tests handling of upload failures @@ -240,10 +259,12 @@ func TestProcessSingleBatchWithFailure(t *testing.T) { // Verify results batchInfo, err := batchService.Get(ctx, clientID, batchID) require.NoError(t, err) - assert.Equal(t, int32(2), batchInfo.ProcessedDocuments) // 1st and 3rd succeeded - assert.Equal(t, int32(1), batchInfo.FailedDocuments) // 2nd failed - assert.Equal(t, "completed", batchInfo.Status) // Status is still completed since some succeeded + assert.Equal(t, "completed", batchInfo.Status) // Status is still completed since some succeeded assert.Contains(t, batchInfo.FailedFilenames, "document_2.pdf") + + // Derived counts: 2 submitted (non-terminal), 1 failed_upload (terminal) + assert.Equal(t, int32(0), batchInfo.ProcessedDocuments, "submitted is non-terminal") + assert.Equal(t, int32(1), batchInfo.FailedDocuments, "2nd file failed upload") } // TestDownloadZipFromS3 tests downloading a ZIP file from S3 @@ -498,7 +519,7 @@ func TestProcessBatchWithNestedFolders(t *testing.T) { require.NoError(t, err) // Create batch - batchID, err := batchService.CreateWithStorage(ctx, clientID, "nested.zip", 7, bucket, archiveKey, int64(len(zipContent))) + batchID, err := batchService.CreateWithStorage(ctx, clientID, "nested.zip", 8, bucket, archiveKey, int64(len(zipContent))) require.NoError(t, err) // Use the real upload handler that creates documents in the database @@ -524,9 +545,11 @@ func TestProcessBatchWithNestedFolders(t *testing.T) { // Verify batch status batchInfo, err := batchService.Get(ctx, clientID, batchID) require.NoError(t, err) - assert.Equal(t, int32(7), batchInfo.ProcessedDocuments) // 7 PDFs - assert.Equal(t, int32(1), batchInfo.InvalidTypeDocuments) // 1 txt file assert.Equal(t, "completed", batchInfo.Status) + assert.Equal(t, int32(8), batchInfo.TotalDocuments, "7 PDFs + 1 TXT") + // After extraction, all outcomes are 'submitted' (non-terminal). + // Derived ProcessedDocuments only counts terminal outcomes. + assert.Equal(t, int32(0), batchInfo.InvalidTypeDocuments, "all types accepted") // Manually trigger document initialization for uploaded files since S3 notifications // don't work in test environment. Get all document uploads for this batch. @@ -562,8 +585,8 @@ func TestProcessBatchWithNestedFolders(t *testing.T) { batchDocs, err := cfg.GetDBQueries().ListDocumentsByBatch(ctx, &batchID) require.NoError(t, err) - // Verify we have the expected number of documents - assert.Equal(t, 7, len(batchDocs), "Should have exactly 7 documents in database") + // Verify we have the expected number of documents (7 PDFs + 1 TXT) + assert.Equal(t, 8, len(batchDocs), "Should have exactly 8 documents in database") // Verify filenames are preserved with their paths foundFilenames := make(map[string]bool) @@ -582,6 +605,7 @@ func TestProcessBatchWithNestedFolders(t *testing.T) { "folderb/folderc/file4.pdf", "folderb/file5.pdf", "deep/nested/structure/test/file6.pdf", + "foldera/readme.txt", } for _, expectedFilename := range expectedFilenames { @@ -874,9 +898,10 @@ func TestProcessZipFile_MixedOutcomes(t *testing.T) { outcomeMap[o.Filename] = o.Outcome } + // All three types are now accepted assert.Equal(t, "submitted", outcomeMap["document.pdf"]) - assert.Equal(t, "invalid_type", outcomeMap["notes.txt"]) - assert.Equal(t, "invalid_type", outcomeMap["report.docx"]) + assert.Equal(t, "submitted", outcomeMap["notes.txt"]) + assert.Equal(t, "submitted", outcomeMap["report.docx"]) } // sha256Hash computes the hex-encoded SHA-256 hash of data. @@ -986,3 +1011,269 @@ func TestProcessBatchWithDuplicateFilenames(t *testing.T) { assert.Contains(t, uploadedDocs["folder2/document.pdf"], "Folder2 document") assert.Contains(t, uploadedDocs["folder1/subfolder/document.pdf"], "Subfolder document") } + +// TestProcessBatchWithAllSupportedFileTypes tests the full multi-format batch upload pipeline. +// A batch ZIP containing one file of each supported type is uploaded and every document +// ends up in the system as a first-class document with an ID. This is the critical +// integration test for multi-format support. +func TestProcessBatchWithAllSupportedFileTypes(t *testing.T) { + if testing.Short() { + t.SkipNow() + } + + ctx := t.Context() + cfg := &BaseConfig{} + _ = serviceconfig.InitializeConfig(cfg) + test.CreateDB(t, cfg) + test.CreateAWSResources(t, cfg) + + clientID := "test_multiformat_batch" + test.CreateTestClient(t, cfg, clientID, "Test Multi-Format Batch Client") + + batchService := batch.New(cfg) + s3ClientInterface := cfg.GetStoreClient() + s3Client, ok := s3ClientInterface.(*s3.Client) + require.True(t, ok) + bucket := cfg.GetBucket() + + // Build a ZIP containing one file of each supported type in folder structure + zipContent := createMultiFormatZIP(t) + archiveKey := fmt.Sprintf("test/%s/multiformat.zip", clientID) + + _, err := s3Client.PutObject(ctx, &s3.PutObjectInput{ + Bucket: aws.String(bucket), + Key: aws.String(archiveKey), + Body: bytes.NewReader(zipContent), + }) + require.NoError(t, err) + + // 10 files total: PDF, TIFF, JPEG, PNG, BMP, DOCX, XLSX, PPTX, TXT, EML + batchID, err := batchService.CreateWithStorage(ctx, clientID, "multiformat.zip", 10, bucket, archiveKey, int64(len(zipContent))) + require.NoError(t, err) + + // Use the real upload handler that persists to the database + uploadHandler := createDocumentUploadHandler(cfg) + + batchDetails := &batch.BatchUploadDetails{ + BatchUploadSummary: batch.BatchUploadSummary{ + ID: batchID, + ClientID: clientID, + OriginalFilename: "multiformat.zip", + Status: "processing", + }, + ArchiveKey: archiveKey, + ArchiveBucket: bucket, + } + + logger := slog.New(slog.NewTextHandler(os.Stdout, nil)) + err = processSingleBatch(ctx, logger, batchService, s3Client, bucket, uploadHandler, batchDetails) + require.NoError(t, err) + + // Verify batch completed successfully + batchInfo, err := batchService.Get(ctx, clientID, batchID) + require.NoError(t, err) + assert.Equal(t, "completed", batchInfo.Status, "batch should complete") + assert.Equal(t, int32(10), batchInfo.TotalDocuments, "all 10 files should be extracted") + // After extraction, outcomes are 'submitted' (non-terminal). Derived counts + // only reflect terminal outcomes so ProcessedDocuments is 0 at this stage. + assert.Equal(t, int32(0), batchInfo.FailedDocuments, "no files should fail") + assert.Equal(t, int32(0), batchInfo.InvalidTypeDocuments, "no files should be invalid type") + + // Verify outcomes: every file should be submitted + outcomes, err := batchService.ListOutcomes(ctx, batchID) + require.NoError(t, err) + assert.Len(t, outcomes, 10, "should have 10 outcomes") + + for _, o := range outcomes { + assert.Equal(t, "submitted", o.Outcome, + "file %s should be submitted, got %s", o.Filename, o.Outcome) + } + + // Verify folder structure is preserved in outcomes + outcomeFilenames := make(map[string]bool) + for _, o := range outcomes { + outcomeFilenames[o.Filename] = true + } + + expectedFiles := []string{ + "documents/report.pdf", + "images/scan.tiff", + "images/photo.jpeg", + "images/diagram.png", + "images/legacy.bmp", + "office/proposal.docx", + "office/data.xlsx", + "office/slides.pptx", + "text/notes.txt", + "email/message.eml", + } + for _, f := range expectedFiles { + assert.True(t, outcomeFilenames[f], "should have outcome for %s", f) + } +} + +// TestProcessBatchWithMixedValidInvalidFileTypes tests a batch with valid new-format +// files and unsupported files, verifying that valid files succeed and unsupported +// files get appropriate rejection without aborting the batch. +func TestProcessBatchWithMixedValidInvalidFileTypes(t *testing.T) { + if testing.Short() { + t.SkipNow() + } + + ctx := t.Context() + cfg := &BaseConfig{} + _ = serviceconfig.InitializeConfig(cfg) + test.CreateDB(t, cfg) + test.CreateAWSResources(t, cfg) + + clientID := "test_mixed_valid_invalid" + test.CreateTestClient(t, cfg, clientID, "Test Mixed Valid Invalid Client") + + batchService := batch.New(cfg) + s3ClientInterface := cfg.GetStoreClient() + s3Client, ok := s3ClientInterface.(*s3.Client) + require.True(t, ok) + bucket := cfg.GetBucket() + + // Create ZIP with mix of valid and unsupported files + zipContent := createMixedValidInvalidZIP(t) + archiveKey := fmt.Sprintf("test/%s/mixed_valid_invalid.zip", clientID) + + _, err := s3Client.PutObject(ctx, &s3.PutObjectInput{ + Bucket: aws.String(bucket), + Key: aws.String(archiveKey), + Body: bytes.NewReader(zipContent), + }) + require.NoError(t, err) + + batchID, err := batchService.CreateWithStorage(ctx, clientID, "mixed_valid_invalid.zip", 5, bucket, archiveKey, int64(len(zipContent))) + require.NoError(t, err) + + uploadHandler := func(_ context.Context, _ string, docData io.Reader, _ string, _ *uuid.UUID) error { + _, _ = io.ReadAll(docData) + return nil + } + + batchDetails := &batch.BatchUploadDetails{ + BatchUploadSummary: batch.BatchUploadSummary{ + ID: batchID, + ClientID: clientID, + OriginalFilename: "mixed_valid_invalid.zip", + Status: "processing", + }, + ArchiveKey: archiveKey, + ArchiveBucket: bucket, + } + + logger := slog.New(slog.NewTextHandler(os.Stdout, nil)) + err = processSingleBatch(ctx, logger, batchService, s3Client, bucket, uploadHandler, batchDetails) + require.NoError(t, err) + + // Batch should still complete (not fail) because some files succeeded + batchInfo, err := batchService.Get(ctx, clientID, batchID) + require.NoError(t, err) + assert.Equal(t, "completed", batchInfo.Status) + // Derived counts: 3 submitted (non-terminal), 2 invalid_type (terminal) + assert.Equal(t, int32(0), batchInfo.ProcessedDocuments, "submitted is non-terminal") + assert.Equal(t, int32(2), batchInfo.InvalidTypeDocuments, "2 unsupported files") + + outcomes, err := batchService.ListOutcomes(ctx, batchID) + require.NoError(t, err) + + outcomeMap := map[string]string{} + for _, o := range outcomes { + outcomeMap[o.Filename] = o.Outcome + } + + // Valid files submitted + assert.Equal(t, "submitted", outcomeMap["report.pdf"]) + assert.Equal(t, "submitted", outcomeMap["notes.txt"]) + assert.Equal(t, "submitted", outcomeMap["photo.png"]) + + // Unsupported files rejected + assert.Equal(t, "invalid_type", outcomeMap["malware.exe"]) + assert.Equal(t, "invalid_type", outcomeMap["archive.zip"]) +} + +// createMultiFormatZIP creates a ZIP with one valid file of each supported type +// organized in folders. +func createMultiFormatZIP(t *testing.T) []byte { + t.Helper() + + // Read fixture files from the types testdata directory + fixtureDir := "../../document/types/testdata/multiformat" + + files := []struct { + zipPath string + fixtureName string + }{ + {"documents/report.pdf", ""}, // PDF needs to be inline (no fixture) + {"images/scan.tiff", "valid.tiff"}, + {"images/photo.jpeg", "valid.jpeg"}, + {"images/diagram.png", "valid.png"}, + {"images/legacy.bmp", "valid.bmp"}, + {"office/proposal.docx", "valid.docx"}, + {"office/data.xlsx", "valid.xlsx"}, + {"office/slides.pptx", "valid.pptx"}, + {"text/notes.txt", "valid.txt"}, + {"email/message.eml", "valid.eml"}, + } + + var buf bytes.Buffer + zipWriter := zip.NewWriter(&buf) + + for _, f := range files { + var data []byte + var err error + + if f.fixtureName == "" { + // Inline PDF content + data = []byte("%%PDF-1.4\n%%Multi-format test PDF\n%%%%EOF") + } else { + data, err = os.ReadFile(fmt.Sprintf("%s/%s", fixtureDir, f.fixtureName)) + require.NoError(t, err, "failed to read fixture %s", f.fixtureName) + } + + w, err := zipWriter.Create(f.zipPath) + require.NoError(t, err) + _, err = w.Write(data) + require.NoError(t, err) + } + + require.NoError(t, zipWriter.Close()) + return buf.Bytes() +} + +// createMixedValidInvalidZIP creates a ZIP with valid supported files and unsupported files. +func createMixedValidInvalidZIP(t *testing.T) []byte { + t.Helper() + + files := []struct { + name string + content []byte + }{ + {"report.pdf", []byte("%%PDF-1.4\n%%Test\n%%%%EOF")}, + {"notes.txt", []byte("This is a valid text file")}, + {"photo.png", nil}, // will be loaded from fixture + {"malware.exe", []byte("MZ\x90\x00\x03\x00")}, // PE signature + {"archive.zip", []byte("Not a real zip but has .zip extension")}, + } + + // Load PNG fixture + pngData, err := os.ReadFile("../../document/types/testdata/multiformat/valid.png") + require.NoError(t, err) + files[2].content = pngData + + var buf bytes.Buffer + zipWriter := zip.NewWriter(&buf) + + for _, f := range files { + w, err := zipWriter.Create(f.name) + require.NoError(t, err) + _, err = w.Write(f.content) + require.NoError(t, err) + } + + require.NoError(t, zipWriter.Close()) + return buf.Bytes() +} diff --git a/scripts/manual_tests/test_zip_all_types_upload.sh b/scripts/manual_tests/test_zip_all_types_upload.sh new file mode 100755 index 00000000..feebf8d3 --- /dev/null +++ b/scripts/manual_tests/test_zip_all_types_upload.sh @@ -0,0 +1,765 @@ +#!/bin/bash + +# Test script for multi-type ZIP batch upload functionality +# Exercises all supported file types through the full processing pipeline +# +# Prerequisites: +# - Local stack running: task compose:refresh +# - Python3 available (stdlib only for runtime, PIL only for JPEG generation) +# +# REST API operations tested: +# - GET /metrics - Service health +# - POST /client - Create test client +# - POST /client/{CLIENT_ID}/document/batch - Upload ZIP +# - GET /client/{CLIENT_ID}/document/batch/{BATCH_ID} - Poll batch status +# - POST /client/{CLIENT_ID}/document/batch (invalid) - Reject non-ZIP +# +# File types tested (valid + invalid for each): +# PDF, TIFF, JPEG, PNG, BMP, DOCX, XLSX, PPTX, TXT, EML + +set -e + +# --- Configuration --- +BASE_URL="http://localhost:8080" +CLIENT_ID="test_alltypes_$(date +%s)" +ZIP_FILE="test_all_types_batch.zip" +TEMP_DIR="temp_all_types_structure" +TOTAL_VALID=10 +TOTAL_INVALID=10 +TOTAL_FILES=$((TOTAL_VALID + TOTAL_INVALID)) + +# --- Terminal outcome constants --- +TERMINAL_OUTCOMES="duplicate init_duplicate failed_open failed_read failed_s3_upload failed_upload invalid_type clean_passed clean_failed sync_skipped" + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Logging functions +log_info() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +log_warn() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +log_step() { + echo -e "${BLUE}[STEP]${NC} $1" +} + +# Check if service is running +check_service() { + log_step "Checking if queryAPI service is running..." + if ! curl -s "$BASE_URL/metrics" > /dev/null 2>&1; then + log_error "queryAPI service is not running at $BASE_URL" + log_info "Please start the stack with: task compose:refresh" + exit 1 + fi + log_info "Service is running" +} + +# Create client (idempotent) +create_client() { + log_step "Creating test client: $CLIENT_ID" + + response=$(curl -s -w "\n%{http_code}" -X POST "$BASE_URL/client" \ + -H "Content-Type: application/json" \ + -d "{\"id\":\"$CLIENT_ID\",\"name\":\"Test AllTypes $CLIENT_ID\"}" 2>/dev/null || echo "000") + + http_code=$(echo "$response" | tail -n1) + + if [ "$http_code" = "201" ] || [ "$http_code" = "200" ]; then + log_info "Client created: $CLIENT_ID" + elif [ "$http_code" = "409" ] || [ "$http_code" = "400" ]; then + log_info "Client already exists: $CLIENT_ID" + else + log_warn "Unexpected response when creating client (HTTP $http_code), continuing..." + fi +} + +# Enable CanSync flag for client +enable_client_sync() { + log_step "Enabling CanSync flag for client: $CLIENT_ID" + + existing=$(docker exec deployments-db-1 psql -U postgres -d query_orchestration -t -c \ + "SELECT COUNT(*) FROM clientcansync WHERE clientid='$CLIENT_ID';" 2>/dev/null | tr -d ' ') + + if [ "$existing" = "0" ]; then + docker exec deployments-db-1 psql -U postgres -d query_orchestration -c \ + "INSERT INTO clientcansync (clientid, cansync) VALUES ('$CLIENT_ID', true);" >/dev/null 2>&1 + else + docker exec deployments-db-1 psql -U postgres -d query_orchestration -c \ + "UPDATE clientcansync SET cansync = true WHERE clientid='$CLIENT_ID';" >/dev/null 2>&1 + fi + + if [ $? -eq 0 ]; then + log_info "CanSync flag enabled" + return 0 + else + log_error "Failed to enable CanSync flag" + return 1 + fi +} + +# Generate all test files using inline Python3 +generate_test_files() { + log_step "Generating test files for all supported types..." + rm -rf "$TEMP_DIR" + mkdir -p "$TEMP_DIR/valid" "$TEMP_DIR/invalid" + + # Copy known-good PDF + cp ./test.pdf.batch/test.pdf "$TEMP_DIR/valid/test_document.pdf" + + # Generate all other files via Python + export TEMP_DIR + python3 << 'PYEOF' +import struct, zlib, zipfile, os, base64 +from email.message import EmailMessage + +TEMP_DIR = os.environ["TEMP_DIR"] +valid_dir = os.path.join(TEMP_DIR, "valid") +invalid_dir = os.path.join(TEMP_DIR, "invalid") + +# ============================ +# Helper: PNG chunk builder +# ============================ +def png_chunk(chunk_type, data): + chunk = chunk_type + data + length = struct.pack(">I", len(data)) + crc = struct.pack(">I", zlib.crc32(chunk) & 0xFFFFFFFF) + return length + chunk + crc + +# ============================ +# VALID FILES +# ============================ + +# --- PNG (100x100 RGB gradient) --- +def create_valid_png(filepath): + width, height = 100, 100 + signature = b'\x89PNG\r\n\x1a\n' + ihdr_data = struct.pack('>IIBBBBB', width, height, 8, 2, 0, 0, 0) + ihdr = png_chunk(b'IHDR', ihdr_data) + raw = b'' + for y in range(height): + raw += b'\x00' # filter: none + for x in range(width): + r = (x * 255 // max(width - 1, 1)) & 0xFF + g = (y * 255 // max(height - 1, 1)) & 0xFF + b = ((x + y) * 127 // max(width + height - 2, 1)) & 0xFF + raw += struct.pack('BBB', r, g, b) + idat = png_chunk(b'IDAT', zlib.compress(raw)) + iend = png_chunk(b'IEND', b'') + with open(filepath, 'wb') as f: + f.write(signature + ihdr + idat + iend) + +create_valid_png(os.path.join(valid_dir, "test_screenshot.png")) + +# --- BMP (100x100 24-bit RGB gradient) --- +def create_valid_bmp(filepath): + width, height = 100, 100 + row_size = (width * 3 + 3) & ~3 + pixel_size = row_size * height + file_size = 54 + pixel_size + fh = struct.pack('<2sIHHI', b'BM', file_size, 0, 0, 54) + ih = struct.pack(' offset + ifd += ifd_entry(259, 3, 1, 1) # Compression = none + ifd += ifd_entry(262, 3, 1, 2) # PhotometricInterpretation = RGB + ifd += ifd_entry(273, 4, 1, strip_offset) # StripOffsets + ifd += ifd_entry(277, 3, 1, 3) # SamplesPerPixel = 3 + ifd += ifd_entry(278, 3, 1, height) # RowsPerStrip + ifd += ifd_entry(279, 4, 1, strip_size) # StripByteCounts + ifd += ifd_entry(282, 5, 1, xres_offset) # XResolution + ifd += ifd_entry(283, 5, 1, yres_offset) # YResolution + ifd += ifd_entry(296, 3, 1, 2) # ResolutionUnit = inch + ifd += struct.pack(' + + + + +''' + rels = ''' + + +''' + document = ''' + + + Test document content for batch upload validation. This document contains meaningful text to pass the empty content check. + Second paragraph with additional content to ensure validation passes. + +''' + doc_rels = ''' +''' + with zipfile.ZipFile(filepath, 'w', zipfile.ZIP_DEFLATED) as zf: + zf.writestr('[Content_Types].xml', content_types) + zf.writestr('_rels/.rels', rels) + zf.writestr('word/document.xml', document) + zf.writestr('word/_rels/document.xml.rels', doc_rels) + +create_valid_docx(os.path.join(valid_dir, "test_report.docx")) + +# --- XLSX (minimal valid Excel spreadsheet) --- +def create_valid_xlsx(filepath): + content_types = ''' + + + + + + +''' + rels = ''' + + +''' + workbook = ''' + + + + +''' + wb_rels = ''' + + + +''' + sheet1 = ''' + + + 01 + 242 + +''' + shared_strings = ''' + + Name + Value + Test Data +''' + with zipfile.ZipFile(filepath, 'w', zipfile.ZIP_DEFLATED) as zf: + zf.writestr('[Content_Types].xml', content_types) + zf.writestr('_rels/.rels', rels) + zf.writestr('xl/workbook.xml', workbook) + zf.writestr('xl/_rels/workbook.xml.rels', wb_rels) + zf.writestr('xl/worksheets/sheet1.xml', sheet1) + zf.writestr('xl/sharedStrings.xml', shared_strings) + +create_valid_xlsx(os.path.join(valid_dir, "test_spreadsheet.xlsx")) + +# --- PPTX (minimal valid PowerPoint presentation) --- +def create_valid_pptx(filepath): + content_types = ''' + + + + + +''' + rels = ''' + + +''' + presentation = ''' + + + + +''' + pres_rels = ''' + + +''' + slide1 = ''' + + + + + + + + + + + Test slide content for batch upload validation. + + + + +''' + slide1_rels = ''' +''' + with zipfile.ZipFile(filepath, 'w', zipfile.ZIP_DEFLATED) as zf: + zf.writestr('[Content_Types].xml', content_types) + zf.writestr('_rels/.rels', rels) + zf.writestr('ppt/presentation.xml', presentation) + zf.writestr('ppt/_rels/presentation.xml.rels', pres_rels) + zf.writestr('ppt/slides/slide1.xml', slide1) + zf.writestr('ppt/slides/_rels/slide1.xml.rels', slide1_rels) + +create_valid_pptx(os.path.join(valid_dir, "test_presentation.pptx")) + +# --- TXT --- +def create_valid_txt(filepath): + with open(filepath, 'w', encoding='utf-8') as f: + f.write("Test document for batch upload validation.\n") + f.write("This file contains multiple lines of meaningful text content.\n") + f.write("Line three provides additional content to ensure validation.\n") + f.write("The quick brown fox jumps over the lazy dog.\n") + +create_valid_txt(os.path.join(valid_dir, "test_notes.txt")) + +# --- EML --- +def create_valid_eml(filepath): + msg = EmailMessage() + msg['From'] = 'sender@example.com' + msg['To'] = 'recipient@example.com' + msg['Subject'] = 'Test email for batch upload validation' + msg['Date'] = 'Mon, 01 Jan 2024 12:00:00 +0000' + msg.set_content( + "This is a test email body for batch upload validation.\n" + "It contains multiple lines of plain text content.\n" + "No attachments are included in this message.\n" + ) + with open(filepath, 'w') as f: + f.write(msg.as_string()) + +create_valid_eml(os.path.join(valid_dir, "test_email.eml")) + +# ============================ +# INVALID FILES +# ============================ +def write_text_as(filepath, text): + with open(filepath, 'w') as f: + f.write(text) + +def write_binary_as(filepath, data): + with open(filepath, 'wb') as f: + f.write(data) + +# Wrong magic bytes (plain text content with image/office extensions) +write_text_as(os.path.join(invalid_dir, "bad_content.pdf"), + "This is not a valid PDF file. It has no PDF magic bytes.") +write_text_as(os.path.join(invalid_dir, "bad_content.tiff"), + "This is not a valid TIFF file. No TIFF header present.") +write_text_as(os.path.join(invalid_dir, "bad_content.jpeg"), + "This is not a valid JPEG file. Missing SOI marker.") +write_text_as(os.path.join(invalid_dir, "bad_content.png"), + "This is not a valid PNG file. Missing PNG signature.") +write_text_as(os.path.join(invalid_dir, "bad_content.bmp"), + "This is not a valid BMP file. Missing BM header.") +write_text_as(os.path.join(invalid_dir, "bad_content.docx"), + "This is not a valid DOCX file. Not a ZIP archive.") +write_text_as(os.path.join(invalid_dir, "bad_content.xlsx"), + "This is not a valid XLSX file. Not a ZIP archive.") +write_text_as(os.path.join(invalid_dir, "bad_content.pptx"), + "This is not a valid PPTX file. Not a ZIP archive.") + +# TXT: binary content with null bytes +write_binary_as(os.path.join(invalid_dir, "bad_content.txt"), + bytes(range(256)) * 4) + +# EML: no RFC822 headers +write_text_as(os.path.join(invalid_dir, "bad_content.eml"), + "Hello this is just some random text without any email " + "headers at all. No From, To, Subject, or Date headers. " + "No header-body separator either.") + +print("All test files generated successfully.") +PYEOF + + # Count generated files + valid_count=$(find "$TEMP_DIR/valid" -type f | wc -l | tr -d ' ') + invalid_count=$(find "$TEMP_DIR/invalid" -type f | wc -l | tr -d ' ') + log_info "Generated $valid_count valid files and $invalid_count invalid files" + + if [ "$valid_count" -ne "$TOTAL_VALID" ]; then + log_error "Expected $TOTAL_VALID valid files, got $valid_count" + exit 1 + fi + if [ "$invalid_count" -ne "$TOTAL_INVALID" ]; then + log_error "Expected $TOTAL_INVALID invalid files, got $invalid_count" + exit 1 + fi +} + +# Create ZIP from generated files +create_test_zip() { + log_step "Creating ZIP file with all test files..." + rm -f "$ZIP_FILE" + current_dir=$(pwd) + cd "$TEMP_DIR" + zip -q -r "$current_dir/$ZIP_FILE" . + cd "$current_dir" + file_size=$(stat -f%z "$ZIP_FILE" 2>/dev/null || stat -c%s "$ZIP_FILE" 2>/dev/null) + log_info "Created $ZIP_FILE ($file_size bytes)" +} + +# Upload ZIP batch +upload_batch() { + log_step "Uploading ZIP batch..." + + response=$(curl -s -w "\n%{http_code}" -X POST "$BASE_URL/client/$CLIENT_ID/document/batch" \ + -F "archive=@$ZIP_FILE" 2>/dev/null) + + http_code=$(echo "$response" | tail -n1) + response_body=$(echo "$response" | head -n -1) + + if [ "$http_code" = "202" ]; then + BATCH_ID=$(echo "$response_body" | python3 -c " +import sys, json +data = json.load(sys.stdin) +print(data['batch_id']) +") + log_info "Batch uploaded successfully" + log_info "Batch ID: $BATCH_ID" + return 0 + else + log_error "Failed to upload batch (HTTP $http_code)" + echo "$response_body" + return 1 + fi +} + +# Phase 1: Wait for batch status != "processing" +poll_batch_extraction() { + log_step "Waiting for batch extraction to complete (up to 60s)..." + local max_wait=60 elapsed=0 interval=3 + while [ $elapsed -lt $max_wait ]; do + response=$(curl -s "$BASE_URL/client/$CLIENT_ID/document/batch/$BATCH_ID") + status=$(echo "$response" | python3 -c " +import sys, json +data = json.load(sys.stdin) +print(data.get('status', 'unknown')) +") + if [ "$status" != "processing" ]; then + log_info "Batch extraction finished with status: $status" + return 0 + fi + sleep $interval + elapsed=$((elapsed + interval)) + log_info "Batch still extracting... ($elapsed/${max_wait}s)" + done + log_error "Timed out waiting for batch extraction" + return 1 +} + +# Phase 2: Wait for all document outcomes to reach terminal state +poll_pipeline_complete() { + log_step "Waiting for all documents to complete pipeline (up to 180s)..." + local max_wait=180 elapsed=0 interval=5 + while [ $elapsed -lt $max_wait ]; do + response=$(curl -s "$BASE_URL/client/$CLIENT_ID/document/batch/$BATCH_ID") + result=$(echo "$response" | python3 -c " +import sys, json +TERMINAL = {'duplicate','init_duplicate','failed_open','failed_read', + 'failed_s3_upload','failed_upload','invalid_type', + 'clean_passed','clean_failed','sync_skipped'} +data = json.load(sys.stdin) +outcomes = data.get('document_outcomes', []) +total = len(outcomes) +terminal = sum(1 for o in outcomes if o.get('outcome') in TERMINAL) +print(f'{terminal}/{total}') +if total > 0 and terminal == total: + sys.exit(0) +else: + sys.exit(1) +" 2>/dev/null) + exit_code=$? + log_info "Pipeline progress: $result documents at terminal state" + if [ $exit_code -eq 0 ]; then + log_info "All documents have completed pipeline processing" + return 0 + fi + sleep $interval + elapsed=$((elapsed + interval)) + done + log_error "Timed out waiting for pipeline completion" + curl -s "$BASE_URL/client/$CLIENT_ID/document/batch/$BATCH_ID" | python3 -m json.tool + return 1 +} + +# Validate final batch results +validate_results() { + log_step "Validating batch results..." + response=$(curl -s "$BASE_URL/client/$CLIENT_ID/document/batch/$BATCH_ID") + + BATCH_RESPONSE="$response" python3 << 'PYEOF' +import sys, json, os + +data = json.loads(os.environ["BATCH_RESPONSE"]) +errors = [] + +def check(condition, msg): + if not condition: + errors.append(msg) + +# --- Count assertions --- +check(data["total_documents"] == 20, + f"total_documents: expected 20, got {data['total_documents']}") +check(data["processed_documents"] == 10, + f"processed_documents: expected 10, got {data['processed_documents']}") +check(data["failed_documents"] == 10, + f"failed_documents: expected 10, got {data['failed_documents']}") +check(data["invalid_type_documents"] == 0, + f"invalid_type_documents: expected 0, got {data['invalid_type_documents']}") +check(data["status"] == "completed", + f"status: expected 'completed', got '{data['status']}'") +check(data.get("progress_percent") == 100, + f"progress_percent: expected 100, got {data.get('progress_percent')}") +check(data.get("completed_at") is not None, + "completed_at: expected not null") + +# --- Per-file outcome assertions --- +valid_files = { + "valid/test_document.pdf", + "valid/test_image.tiff", + "valid/test_photo.jpeg", + "valid/test_screenshot.png", + "valid/test_bitmap.bmp", + "valid/test_report.docx", + "valid/test_spreadsheet.xlsx", + "valid/test_presentation.pptx", + "valid/test_notes.txt", + "valid/test_email.eml", +} + +invalid_files = { + "invalid/bad_content.pdf", + "invalid/bad_content.tiff", + "invalid/bad_content.jpeg", + "invalid/bad_content.png", + "invalid/bad_content.bmp", + "invalid/bad_content.docx", + "invalid/bad_content.xlsx", + "invalid/bad_content.pptx", + "invalid/bad_content.txt", + "invalid/bad_content.eml", +} + +outcomes = data.get("document_outcomes", []) +outcome_map = {o["filename"]: o for o in outcomes} + +# Assert: all valid files must reach clean_passed with a document_id +for f in sorted(valid_files): + if f not in outcome_map: + errors.append(f"Missing outcome for valid file: {f}") + else: + o = outcome_map[f] + if o["outcome"] != "clean_passed": + detail = o.get("error_detail") or o.get("clean_fail_reason") or "none" + errors.append(f"{f}: expected clean_passed, got {o['outcome']} (detail: {detail})") + if not o.get("document_id"): + errors.append(f"{f}: expected document_id to be set") + +# Assert: all invalid files must reach clean_failed with a clean_fail_reason +for f in sorted(invalid_files): + if f not in outcome_map: + errors.append(f"Missing outcome for invalid file: {f}") + else: + o = outcome_map[f] + if o["outcome"] != "clean_failed": + detail = o.get("error_detail") or o.get("clean_fail_reason") or "none" + errors.append(f"{f}: expected clean_failed, got {o['outcome']} (detail: {detail})") + if not o.get("clean_fail_reason"): + errors.append(f"{f}: expected clean_fail_reason to be set") + +# Verify all expected files are present in outcomes +outcome_filenames = set(outcome_map.keys()) +missing_valid = valid_files - outcome_filenames +missing_invalid = invalid_files - outcome_filenames +if missing_valid: + errors.append(f"Missing valid files in outcomes: {missing_valid}") +if missing_invalid: + errors.append(f"Missing invalid files in outcomes: {missing_invalid}") +check(len(outcomes) == 20, f"Expected 20 outcomes, got {len(outcomes)}") + +# --- Report --- +if errors: + print(f"VALIDATION FAILED ({len(errors)} errors):") + for e in errors: + print(f" - {e}") + print("\nFull batch status:") + print(json.dumps(data, indent=2, default=str)) + sys.exit(1) +else: + passed = sum(1 for o in outcomes if o["outcome"] == "clean_passed") + failed = sum(1 for o in outcomes if o["outcome"] == "clean_failed") + print("All assertions passed!") + print(f" Valid files (clean_passed): {passed}") + print(f" Invalid files (clean_failed): {failed}") + print(f" Total documents: {data['total_documents']}") + print(f" Progress: {data.get('progress_percent')}%") + sys.exit(0) +PYEOF + + if [ $? -ne 0 ]; then + log_error "Validation FAILED" + return 1 + fi + log_info "Validation PASSED" + return 0 +} + +# Test invalid ZIP upload +test_invalid_zip_upload() { + log_step "Testing invalid file upload (should fail with 400)..." + + echo "This is not a ZIP file" > invalid.txt + + response=$(curl -s -w "\n%{http_code}" -X POST "$BASE_URL/client/$CLIENT_ID/document/batch" \ + -F "archive=@invalid.txt" 2>/dev/null) + + http_code=$(echo "$response" | tail -n1) + rm -f invalid.txt + + if [ "$http_code" = "400" ]; then + log_info "Invalid file correctly rejected (HTTP 400)" + return 0 + else + log_warn "Expected HTTP 400 for invalid file, got HTTP $http_code" + return 1 + fi +} + +# Cleanup +cleanup() { + log_info "Cleaning up..." + rm -f "$ZIP_FILE" invalid.txt + rm -rf "$TEMP_DIR" + log_info "Cleanup complete" +} + +# Main test flow +main() { + log_step "Starting multi-type ZIP batch upload test..." + log_info "Testing file types: PDF, TIFF, JPEG, PNG, BMP, DOCX, XLSX, PPTX, TXT, EML" + log_info "Using client ID: $CLIENT_ID" + + trap cleanup EXIT + + check_service + generate_test_files + create_test_zip + create_client + enable_client_sync + + if upload_batch; then + poll_batch_extraction + poll_pipeline_complete + validate_results + + test_invalid_zip_upload + + log_info "All tests completed successfully!" + else + log_error "Batch upload failed, skipping remaining tests" + exit 1 + fi +} + +main "$@" diff --git a/vendor/github.com/chai2010/tiff/.gitignore b/vendor/github.com/chai2010/tiff/.gitignore new file mode 100644 index 00000000..bfba147d --- /dev/null +++ b/vendor/github.com/chai2010/tiff/.gitignore @@ -0,0 +1 @@ +examples/z_* diff --git a/vendor/github.com/chai2010/tiff/.travis.yml b/vendor/github.com/chai2010/tiff/.travis.yml new file mode 100644 index 00000000..245a2f51 --- /dev/null +++ b/vendor/github.com/chai2010/tiff/.travis.yml @@ -0,0 +1,6 @@ +language: go + +go: + - 1.3 + - 1.4 + - tip diff --git a/vendor/github.com/chai2010/tiff/LICENSE b/vendor/github.com/chai2010/tiff/LICENSE new file mode 100644 index 00000000..a424cdda --- /dev/null +++ b/vendor/github.com/chai2010/tiff/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2015 . All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/chai2010/tiff/README.md b/vendor/github.com/chai2010/tiff/README.md new file mode 100644 index 00000000..439c961c --- /dev/null +++ b/vendor/github.com/chai2010/tiff/README.md @@ -0,0 +1,92 @@ +- *Go语言QQ群: 102319854, 1055927514* +- *凹语言(凹读音“Wa”)(The Wa Programming Language): https://github.com/wa-lang/wa* + +---- + +TIFF for Go +=========== + +[![Build Status](https://travis-ci.org/chai2010/tiff.svg)](https://travis-ci.org/chai2010/tiff) +[![GoDoc](https://godoc.org/github.com/chai2010/tiff?status.svg)](https://godoc.org/github.com/chai2010/tiff) + + +**Features:** + +1. Support BigTiff +2. Support decode multiple image +3. Support decode subifd image +4. Support RGB format +5. Support Float DataType +6. More ... + +Install +======= + +1. `go get github.com/chai2010/tiff` +2. `go run hello.go` + +Example +======= + +```Go +package main + +import ( + "bytes" + "fmt" + "io/ioutil" + "log" + "path/filepath" + + tiff "github.com/chai2010/tiff" +) + +func main() { + var data []byte + var err error + + var files = []string{ + "./testdata/BigTIFFSamples/BigTIFFSubIFD8.tif", + "./testdata/multipage/multipage-gopher.tif", + } + for _, filename := range files { + // Load file data + if data, err = ioutil.ReadFile(filename); err != nil { + log.Fatal(err) + } + + // Decode tiff + m, errors, err := tiff.DecodeAll(bytes.NewReader(data)) + if err != nil { + log.Println(err) + } + + // Encode tiff + for i := 0; i < len(m); i++ { + for j := 0; j < len(m[i]); j++ { + newname := fmt.Sprintf("%s-%02d-%02d.tiff", filepath.Base(filename), i, j) + if errors[i][j] != nil { + log.Printf("%s: %v\n", newname, err) + continue + } + + var buf bytes.Buffer + if err = tiff.Encode(&buf, m[i][j], nil); err != nil { + log.Fatal(err) + } + if err = ioutil.WriteFile(newname, buf.Bytes(), 0666); err != nil { + log.Fatal(err) + } + fmt.Printf("Save %s ok\n", newname) + } + } + } +} +``` + +BUGS +==== + +Report bugs to . + +Thanks! diff --git a/vendor/github.com/chai2010/tiff/bits_io.go b/vendor/github.com/chai2010/tiff/bits_io.go new file mode 100644 index 00000000..a4429196 --- /dev/null +++ b/vendor/github.com/chai2010/tiff/bits_io.go @@ -0,0 +1,42 @@ +// Copyright 2014 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tiff + +type bitsReader struct { + buf []byte + off int // Current offset in buf. + v uint32 // Buffer value for reading with arbitrary bit depths. + nbits uint // Remaining number of bits in v. +} + +func newBitsReader(data []byte) *bitsReader { + return &bitsReader{ + buf: data, + } +} + +// readBits reads n bits from the internal buffer starting at the current offset. +func (p *bitsReader) ReadBits(n uint) (v uint32, ok bool) { + for p.nbits < n { + p.v <<= 8 + if p.off >= len(p.buf) { + return 0, false + } + p.v |= uint32(p.buf[p.off]) + p.off++ + p.nbits += 8 + } + p.nbits -= n + rv := p.v >> p.nbits + p.v &^= rv << p.nbits + return rv, true +} + +// flushBits discards the unread bits in the buffer used by readBits. +// It is used at the end of a line. +func (p *bitsReader) flushBits() { + p.v = 0 + p.nbits = 0 +} diff --git a/vendor/github.com/chai2010/tiff/compress.go b/vendor/github.com/chai2010/tiff/compress.go new file mode 100644 index 00000000..ea5b400a --- /dev/null +++ b/vendor/github.com/chai2010/tiff/compress.go @@ -0,0 +1,146 @@ +// Copyright 2015 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tiff + +import ( + "bufio" + "compress/zlib" + "fmt" + "io" + "io/ioutil" + + "github.com/chai2010/tiff/internal/fax" +) + +func (p TagValue_CompressionType) Decode(r io.Reader, width, height int) (data []byte, err error) { + switch p { + case TagValue_CompressionType_None, TagValue_CompressionType_Nil: + return p.decode_None(r) + case TagValue_CompressionType_CCITT: + return p.decode_CCITT(r) + case TagValue_CompressionType_G3: + return p.decode_G3(r, width, height) + case TagValue_CompressionType_G4: + return p.decode_G4(r, width, height) + case TagValue_CompressionType_LZW: + return p.decode_LZW(r) + case TagValue_CompressionType_JPEGOld: + return p.decode_JPEGOld(r) + case TagValue_CompressionType_JPEG: + return p.decode_JPEG(r) + case TagValue_CompressionType_Deflate: + return p.decode_Deflate(r) + case TagValue_CompressionType_PackBits: + return p.decode_PackBits(r) + case TagValue_CompressionType_DeflateOld: + return p.decode_DeflateOld(r) + } + err = fmt.Errorf("tiff: unsupport %v compression type", int(p)) + return +} + +func (p TagValue_CompressionType) decode_None(r io.Reader) (data []byte, err error) { + data, err = ioutil.ReadAll(r) + return +} + +func (p TagValue_CompressionType) decode_CCITT(r io.Reader) (data []byte, err error) { + err = fmt.Errorf("tiff: unsupport %v compression type", "CCITT") + return +} + +func (p TagValue_CompressionType) decode_G3(r io.Reader, width, height int) (data []byte, err error) { + return p.decode_G4(r, width, height) +} + +func (p TagValue_CompressionType) decode_G4(r io.Reader, width, height int) (data []byte, err error) { + br, ok := r.(io.ByteReader) + if !ok { + br = bufio.NewReader(r) + } + + return fax.DecodeG4Pixels(br, width, height) +} + +func (p TagValue_CompressionType) decode_LZW(r io.Reader) (data []byte, err error) { + lzwReader := newLzwReader(r, lzwMSB, 8) + data, err = ioutil.ReadAll(lzwReader) + lzwReader.Close() + return +} + +func (p TagValue_CompressionType) decode_JPEGOld(r io.Reader) (data []byte, err error) { + println("decode_JPEGOld") + err = fmt.Errorf("tiff: unsupport %v compression type", "JPEGOld") + return +} + +func (p TagValue_CompressionType) decode_JPEG(r io.Reader) (data []byte, err error) { + err = fmt.Errorf("tiff: unsupport %v compression type", "JPEG") + return +} + +func (p TagValue_CompressionType) decode_Deflate(r io.Reader) (data []byte, err error) { + zlibReader, err := zlib.NewReader(r) + if err != nil { + return nil, err + } + data, err = ioutil.ReadAll(zlibReader) + zlibReader.Close() + return +} + +func (p TagValue_CompressionType) decode_DeflateOld(r io.Reader) (data []byte, err error) { + zlibReader, err := zlib.NewReader(r) + if err != nil { + return nil, err + } + data, err = ioutil.ReadAll(zlibReader) + zlibReader.Close() + return +} + +func (p TagValue_CompressionType) decode_PackBits(r io.Reader) (data []byte, err error) { + type byteReader interface { + io.Reader + io.ByteReader + } + + buf := make([]byte, 128) + dst := make([]byte, 0, 1024) + br, ok := r.(byteReader) + if !ok { + br = bufio.NewReader(r) + } + + for { + b, err := br.ReadByte() + if err != nil { + if err == io.EOF { + return dst, nil + } + return nil, err + } + code := int(int8(b)) + switch { + case code >= 0: + n, err := io.ReadFull(br, buf[:code+1]) + if err != nil { + return nil, err + } + dst = append(dst, buf[:n]...) + case code == -128: + // No-op. + default: + if b, err = br.ReadByte(); err != nil { + return nil, err + } + for j := 0; j < 1-code; j++ { + buf[j] = b + } + dst = append(dst, buf[:1-code]...) + } + } +} diff --git a/vendor/github.com/chai2010/tiff/decoder.go b/vendor/github.com/chai2010/tiff/decoder.go new file mode 100644 index 00000000..b6c0aac5 --- /dev/null +++ b/vendor/github.com/chai2010/tiff/decoder.go @@ -0,0 +1,104 @@ +// Copyright 2015 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tiff + +import ( + "image" + "io" +) + +// DecodeConfig returns the color model and dimensions of a TIFF image without +// decoding the entire image. +func DecodeConfig(r io.Reader) (cfg image.Config, err error) { + var p *Reader + if p, err = OpenReader(r); err != nil { + return + } + defer p.Close() + + return p.ImageConfig(0, 0) +} + +func DecodeConfigAll(r io.Reader) (cfg [][]image.Config, errors [][]error, err error) { + var p *Reader + if p, err = OpenReader(r); err != nil { + return + } + defer p.Close() + + cfg = make([][]image.Config, len(p.Ifd)) + errors = make([][]error, len(p.Ifd)) + +Loop: + for i := 0; i < len(p.Ifd); i++ { + errors[i] = make([]error, len(p.Ifd[i])) + for j := 0; j < len(p.Ifd[i]); j++ { + if cfg[i][j], errors[i][j] = p.Ifd[i][j].ImageConfig(); errors[i][j] != nil { + break Loop + } + } + } + for i := 0; i < len(errors); i++ { + for j := 0; j < len(errors[i]); j++ { + if errors[i][j] != nil { + err = errors[i][j] + return + } + } + } + + return +} + +// Decode reads a TIFF image from r and returns it as an image.Image. +// The type of Image returned depends on the contents of the TIFF. +func Decode(r io.Reader) (m image.Image, err error) { + var p *Reader + if p, err = OpenReader(r); err != nil { + return + } + defer p.Close() + + m, err = p.DecodeImage(0, 0) + return +} + +func DecodeAll(r io.Reader) (m [][]image.Image, errors [][]error, err error) { + var p *Reader + if p, err = OpenReader(r); err != nil { + return + } + defer p.Close() + + m = make([][]image.Image, p.ImageNum()) + errors = make([][]error, p.ImageNum()) + +Loop: + for i := 0; i < p.ImageNum(); i++ { + m[i] = make([]image.Image, p.SubImageNum(i)) + errors[i] = make([]error, len(p.Ifd[i])) + for j := 0; j < p.SubImageNum(i); j++ { + if m[i][j], errors[i][j] = p.DecodeImage(i, j); errors[i][j] != nil { + break Loop + } + } + } + for i := 0; i < len(errors); i++ { + for j := 0; j < len(errors[i]); j++ { + if errors[i][j] != nil { + err = errors[i][j] + return + } + } + } + return +} + +func init() { + image.RegisterFormat("tiff", ClassicTiffLittleEnding, Decode, DecodeConfig) + image.RegisterFormat("tiff", ClassicTiffBigEnding, Decode, DecodeConfig) + image.RegisterFormat("tiff", BigTiffLittleEnding, Decode, DecodeConfig) + image.RegisterFormat("tiff", BigTiffBigEnding, Decode, DecodeConfig) +} diff --git a/vendor/github.com/chai2010/tiff/doc.go b/vendor/github.com/chai2010/tiff/doc.go new file mode 100644 index 00000000..e1e866bf --- /dev/null +++ b/vendor/github.com/chai2010/tiff/doc.go @@ -0,0 +1,159 @@ +// Copyright 2014 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* +Package tiff offers a rich TIFF/BigTIFF/GeoTIFF decoder/encoder for Go. + +The Classic TIFF specification is at http://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf + +The Big TIFF specification is at http://www.remotesensing.org/libtiff/bigtiffdesign.html + +The Geo TIFF specification is at http://www.remotesensing.org/geotiff/spec/geotiffhome.html + +TIFF Tags: http://www.awaresystems.be/imaging/tiff/tifftags.html + +Features: + + 1. Support BigTiff + 2. Support decode multiple image + 3. Support decode subifd image + 4. Support RGB format + 5. Support Float DataType + 6. More ... + +Example: + + package main + + import ( + "bytes" + "fmt" + "io/ioutil" + "log" + "path/filepath" + + tiff "github.com/chai2010/tiff" + ) + + func main() { + var data []byte + var err error + + var files = []string{ + "./testdata/BigTIFFSamples/BigTIFFSubIFD8.tif", + "./testdata/multipage/multipage-gopher.tif", + } + for _, filename := range files { + // Load file data + if data, err = ioutil.ReadFile(filename); err != nil { + log.Fatal(err) + } + + // Decode tiff + m, errors, err := tiff.DecodeAll(bytes.NewReader(data)) + if err != nil { + log.Println(err) + } + + // Encode tiff + for i := 0; i < len(m); i++ { + for j := 0; j < len(m[i]); j++ { + newname := fmt.Sprintf("%s-%02d-%02d.tiff", filepath.Base(filename), i, j) + if errors[i][j] != nil { + log.Printf("%s: %v\n", newname, err) + continue + } + + var buf bytes.Buffer + if err = tiff.Encode(&buf, m[i][j], nil); err != nil { + log.Fatal(err) + } + if err = ioutil.WriteFile(newname, buf.Bytes(), 0666); err != nil { + log.Fatal(err) + } + fmt.Printf("Save %s ok\n", newname) + } + } + } + } + +Report bugs to . + +Thanks! +*/ +package tiff + +/* +The Classic TIFF specification is at http://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf + +The Big TIFF specification is at http://www.remotesensing.org/libtiff/bigtiffdesign.html + +The Geo TIFF specification is at http://www.remotesensing.org/geotiff/spec/geotiffhome.html + +Classic TIFF Structure: + + +------------------------------------------------------------------------------+ + | Classic TIFF Structure | + | IFH | + | +-----------------+ | + | | II/MM ([2]byte) | | + | +-----------------+ | + | | 42 (uint16) | IFD | + | +-----------------+ +------------------+ | + | | Offset (uint32) |---->| Num (uint16) | | + | +-----------------+ +------------------+ | + | | Entry ([12]byte) | | + | +------------------+ | + | | Entry ([12]byte) | | + | +------------------+ | + | | ... | IFD | + | +------------------+ +------------------+ | + | IFD Entry | Offset (uint32) |--->| Num (uint16) | | + | +-----------------+ +------------------+ +------------------+ | + | | Tag (uint16) | | Entry ([12]byte) | | + | +-----------------+ +------------------+ | + | | Type (uint16) |<-------------------------| Entry ([12]byte) | | + | +-----------------+ +------------------+ | + | | Count (uint32) | | ... | | + | +-----------------+ +------------------+ | + | | Offset (uint32) |---> Value | Offset (uint32) |--->NULL | + | +-----------------+ +------------------+ | + | | + +------------------------------------------------------------------------------+ + +Big TIFF Structure: + + +------------------------------------------------------------------------------+ + | Big TIFF Structure | + | IFH | + | +-----------------+ | + | | II/MM ([2byte]) | | + | +-----------------+ | + | | 43 (uint16) | | + | +-----------------+ | + | | 8 (uint16) | | + | +-----------------+ | + | | 0 (uint16) | IFD | + | +-----------------+ +------------------+ | + | | Offset (uint64) |---->| Num (uint64) | | + | +-----------------+ +------------------+ | + | | Entry ([20]byte) | | + | +------------------+ | + | | Entry ([20]byte) | | + | +------------------+ | + | | ... | IFD | + | +------------------+ +------------------+ | + | IFD Entry | Offset (uint64) |--->| Num (uint64) | | + | +-----------------+ +------------------+ +------------------+ | + | | Tag (uint16) | | Entry ([12]byte) | | + | +-----------------+ +------------------+ | + | | Type (uint16) |<-------------------------| Entry ([12]byte) | | + | +-----------------+ +------------------+ | + | | Count (uint64) | | ... | | + | +-----------------+ +------------------+ | + | | Offset (uint64) |---> Value | Offset (uint64) |--->NULL | + | +-----------------+ +------------------+ | + | | + +------------------------------------------------------------------------------+ +*/ diff --git a/vendor/github.com/chai2010/tiff/encoder.go b/vendor/github.com/chai2010/tiff/encoder.go new file mode 100644 index 00000000..90407c32 --- /dev/null +++ b/vendor/github.com/chai2010/tiff/encoder.go @@ -0,0 +1,427 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tiff + +import ( + "bytes" + "compress/zlib" + "encoding/binary" + "image" + "io" + "sort" +) + +// The TIFF format allows to choose the order of the different elements freely. +// The basic structure of a TIFF file written by this package is: +// +// 1. Header (8 bytes). +// 2. Image data. +// 3. Image File Directory (IFD). +// 4. "Pointer area" for larger entries in the IFD. + +// We only write little-endian TIFF files. +var enc = binary.LittleEndian + +// An ifdEntry is a single entry in an Image File Directory. +// A value of type DataType_Rational is composed of two 32-bit values, +// thus data contains two uints (numerator and denominator) for a single number. +type ifdEntry struct { + tag TagType + datatype DataType + data []uint32 +} + +func (e ifdEntry) putData(p []byte) { + for _, d := range e.data { + switch e.datatype { + case DataType_Byte, DataType_ASCII: + p[0] = byte(d) + p = p[1:] + case DataType_Short: + enc.PutUint16(p, uint16(d)) + p = p[2:] + case DataType_Long, DataType_Rational: + enc.PutUint32(p, uint32(d)) + p = p[4:] + } + } +} + +type byTag []ifdEntry + +func (d byTag) Len() int { return len(d) } +func (d byTag) Less(i, j int) bool { return d[i].tag < d[j].tag } +func (d byTag) Swap(i, j int) { d[i], d[j] = d[j], d[i] } + +func encodeGray(w io.Writer, pix []uint8, dx, dy, stride int, predictor bool) error { + if !predictor { + return writePix(w, pix, dy, dx, stride) + } + buf := make([]byte, dx) + for y := 0; y < dy; y++ { + min := y*stride + 0 + max := y*stride + dx + off := 0 + var v0 uint8 + for i := min; i < max; i++ { + v1 := pix[i] + buf[off] = v1 - v0 + v0 = v1 + off++ + } + if _, err := w.Write(buf); err != nil { + return err + } + } + return nil +} + +func encodeGray16(w io.Writer, pix []uint8, dx, dy, stride int, predictor bool) error { + buf := make([]byte, dx*2) + for y := 0; y < dy; y++ { + min := y*stride + 0 + max := y*stride + dx*2 + off := 0 + var v0 uint16 + for i := min; i < max; i += 2 { + // An image.Gray16's Pix is in big-endian order. + v1 := uint16(pix[i])<<8 | uint16(pix[i+1]) + if predictor { + v0, v1 = v1, v1-v0 + } + // We only write little-endian TIFF files. + buf[off+0] = byte(v1) + buf[off+1] = byte(v1 >> 8) + off += 2 + } + if _, err := w.Write(buf); err != nil { + return err + } + } + return nil +} + +func encodeRGBA(w io.Writer, pix []uint8, dx, dy, stride int, predictor bool) error { + if !predictor { + return writePix(w, pix, dy, dx*4, stride) + } + buf := make([]byte, dx*4) + for y := 0; y < dy; y++ { + min := y*stride + 0 + max := y*stride + dx*4 + off := 0 + var r0, g0, b0, a0 uint8 + for i := min; i < max; i += 4 { + r1, g1, b1, a1 := pix[i+0], pix[i+1], pix[i+2], pix[i+3] + buf[off+0] = r1 - r0 + buf[off+1] = g1 - g0 + buf[off+2] = b1 - b0 + buf[off+3] = a1 - a0 + off += 4 + r0, g0, b0, a0 = r1, g1, b1, a1 + } + if _, err := w.Write(buf); err != nil { + return err + } + } + return nil +} + +func encodeRGBA64(w io.Writer, pix []uint8, dx, dy, stride int, predictor bool) error { + buf := make([]byte, dx*8) + for y := 0; y < dy; y++ { + min := y*stride + 0 + max := y*stride + dx*8 + off := 0 + var r0, g0, b0, a0 uint16 + for i := min; i < max; i += 8 { + // An image.RGBA64's Pix is in big-endian order. + r1 := uint16(pix[i+0])<<8 | uint16(pix[i+1]) + g1 := uint16(pix[i+2])<<8 | uint16(pix[i+3]) + b1 := uint16(pix[i+4])<<8 | uint16(pix[i+5]) + a1 := uint16(pix[i+6])<<8 | uint16(pix[i+7]) + if predictor { + r0, r1 = r1, r1-r0 + g0, g1 = g1, g1-g0 + b0, b1 = b1, b1-b0 + a0, a1 = a1, a1-a0 + } + // We only write little-endian TIFF files. + buf[off+0] = byte(r1) + buf[off+1] = byte(r1 >> 8) + buf[off+2] = byte(g1) + buf[off+3] = byte(g1 >> 8) + buf[off+4] = byte(b1) + buf[off+5] = byte(b1 >> 8) + buf[off+6] = byte(a1) + buf[off+7] = byte(a1 >> 8) + off += 8 + } + if _, err := w.Write(buf); err != nil { + return err + } + } + return nil +} + +func encode(w io.Writer, m image.Image, predictor bool) error { + bounds := m.Bounds() + buf := make([]byte, 4*bounds.Dx()) + for y := bounds.Min.Y; y < bounds.Max.Y; y++ { + off := 0 + if predictor { + var r0, g0, b0, a0 uint8 + for x := bounds.Min.X; x < bounds.Max.X; x++ { + r, g, b, a := m.At(x, y).RGBA() + r1 := uint8(r >> 8) + g1 := uint8(g >> 8) + b1 := uint8(b >> 8) + a1 := uint8(a >> 8) + buf[off+0] = r1 - r0 + buf[off+1] = g1 - g0 + buf[off+2] = b1 - b0 + buf[off+3] = a1 - a0 + off += 4 + r0, g0, b0, a0 = r1, g1, b1, a1 + } + } else { + for x := bounds.Min.X; x < bounds.Max.X; x++ { + r, g, b, a := m.At(x, y).RGBA() + buf[off+0] = uint8(r >> 8) + buf[off+1] = uint8(g >> 8) + buf[off+2] = uint8(b >> 8) + buf[off+3] = uint8(a >> 8) + off += 4 + } + } + if _, err := w.Write(buf); err != nil { + return err + } + } + return nil +} + +// writePix writes the internal byte array of an image to w. It is less general +// but much faster then encode. writePix is used when pix directly +// corresponds to one of the TIFF image types. +func writePix(w io.Writer, pix []byte, nrows, length, stride int) error { + if length == stride { + _, err := w.Write(pix[:nrows*length]) + return err + } + for ; nrows > 0; nrows-- { + if _, err := w.Write(pix[:length]); err != nil { + return err + } + pix = pix[stride:] + } + return nil +} + +func writeIFD(w io.Writer, ifdOffset int, d []ifdEntry) error { + const ifdLen = 12 + + var buf [ifdLen]byte + // Make space for "pointer area" containing IFD entry data + // longer than 4 bytes. + parea := make([]byte, 1024) + pstart := ifdOffset + ifdLen*len(d) + 6 + var o int // Current offset in parea. + + // The IFD has to be written with the tags in ascending order. + sort.Sort(byTag(d)) + + // Write the number of entries in this IFD. + if err := binary.Write(w, enc, uint16(len(d))); err != nil { + return err + } + for _, ent := range d { + enc.PutUint16(buf[0:2], uint16(ent.tag)) + enc.PutUint16(buf[2:4], uint16(ent.datatype)) + count := uint32(len(ent.data)) + if ent.datatype == DataType_Rational { + count /= 2 + } + enc.PutUint32(buf[4:8], count) + datalen := int(count * uint32(ent.datatype.ByteSize())) + if datalen <= 4 { + ent.putData(buf[8:12]) + } else { + if (o + datalen) > len(parea) { + newlen := len(parea) + 1024 + for (o + datalen) > newlen { + newlen += 1024 + } + newarea := make([]byte, newlen) + copy(newarea, parea) + parea = newarea + } + ent.putData(parea[o : o+datalen]) + enc.PutUint32(buf[8:12], uint32(pstart+o)) + o += datalen + } + if _, err := w.Write(buf[:]); err != nil { + return err + } + } + // The IFD ends with the offset of the next IFD in the file, + // or zero if it is the last one (page 14). + if err := binary.Write(w, enc, uint32(0)); err != nil { + return err + } + _, err := w.Write(parea[:o]) + return err +} + +func EncodeAll(w io.Writer, m [][]image.Image, opt [][]*Options) error { + return nil +} + +// Encode writes the image m to w. opt determines the options used for +// encoding, such as the compression type. If opt is nil, an uncompressed +// image is written. +func Encode(w io.Writer, m image.Image, opt *Options) error { + d := m.Bounds().Size() + + compression := TagValue_CompressionType_None + predictor := false + + _, err := io.WriteString(w, ClassicTiffLittleEnding) + if err != nil { + return err + } + + // Compressed data is written into a buffer first, so that we + // know the compressed size. + var buf bytes.Buffer + // dst holds the destination for the pixel data of the image -- + // either w or a writer to buf. + var dst io.Writer + // imageLen is the length of the pixel data in bytes. + // The offset of the IFD is imageLen + 8 header bytes. + var imageLen int + + switch compression { + case TagValue_CompressionType_None: + dst = w + // Write IFD offset before outputting pixel data. + switch m.(type) { + case *image.Paletted: + imageLen = d.X * d.Y * 1 + case *image.Gray: + imageLen = d.X * d.Y * 1 + case *image.Gray16: + imageLen = d.X * d.Y * 2 + case *image.RGBA64: + imageLen = d.X * d.Y * 8 + case *image.NRGBA64: + imageLen = d.X * d.Y * 8 + default: + imageLen = d.X * d.Y * 4 + } + err = binary.Write(w, enc, uint32(imageLen+8)) + if err != nil { + return err + } + case TagValue_CompressionType_Deflate: + dst = zlib.NewWriter(&buf) + } + + pr := uint32(TagValue_PredictorType_None) + photometricInterpretation := uint32(TagValue_PhotometricType_RGB) + samplesPerPixel := uint32(4) + bitsPerSample := []uint32{8, 8, 8, 8} + extraSamples := uint32(0) + colorMap := []uint32{} + + if predictor { + pr = uint32(TagValue_PredictorType_Horizontal) + } + switch m := m.(type) { + case *image.Paletted: + photometricInterpretation = uint32(TagValue_PhotometricType_Paletted) + samplesPerPixel = 1 + bitsPerSample = []uint32{8} + colorMap = make([]uint32, 256*3) + for i := 0; i < 256 && i < len(m.Palette); i++ { + r, g, b, _ := m.Palette[i].RGBA() + colorMap[i+0*256] = uint32(r) + colorMap[i+1*256] = uint32(g) + colorMap[i+2*256] = uint32(b) + } + err = encodeGray(dst, m.Pix, d.X, d.Y, m.Stride, predictor) + case *image.Gray: + photometricInterpretation = uint32(TagValue_PhotometricType_BlackIsZero) + samplesPerPixel = 1 + bitsPerSample = []uint32{8} + err = encodeGray(dst, m.Pix, d.X, d.Y, m.Stride, predictor) + case *image.Gray16: + photometricInterpretation = uint32(TagValue_PhotometricType_BlackIsZero) + samplesPerPixel = 1 + bitsPerSample = []uint32{16} + err = encodeGray16(dst, m.Pix, d.X, d.Y, m.Stride, predictor) + case *image.NRGBA: + extraSamples = 2 // Unassociated alpha. + err = encodeRGBA(dst, m.Pix, d.X, d.Y, m.Stride, predictor) + case *image.NRGBA64: + extraSamples = 2 // Unassociated alpha. + bitsPerSample = []uint32{16, 16, 16, 16} + err = encodeRGBA64(dst, m.Pix, d.X, d.Y, m.Stride, predictor) + case *image.RGBA: + extraSamples = 1 // Associated alpha. + err = encodeRGBA(dst, m.Pix, d.X, d.Y, m.Stride, predictor) + case *image.RGBA64: + extraSamples = 1 // Associated alpha. + bitsPerSample = []uint32{16, 16, 16, 16} + err = encodeRGBA64(dst, m.Pix, d.X, d.Y, m.Stride, predictor) + default: + extraSamples = 1 // Associated alpha. + err = encode(dst, m, predictor) + } + if err != nil { + return err + } + + if compression != TagValue_CompressionType_None { + if err = dst.(io.Closer).Close(); err != nil { + return err + } + imageLen = buf.Len() + if err = binary.Write(w, enc, uint32(imageLen+8)); err != nil { + return err + } + if _, err = buf.WriteTo(w); err != nil { + return err + } + } + + ifd := []ifdEntry{ + {TagType_ImageWidth, DataType_Short, []uint32{uint32(d.X)}}, + {TagType_ImageLength, DataType_Short, []uint32{uint32(d.Y)}}, + {TagType_BitsPerSample, DataType_Short, bitsPerSample}, + {TagType_Compression, DataType_Short, []uint32{uint32(compression)}}, + {TagType_PhotometricInterpretation, DataType_Short, []uint32{photometricInterpretation}}, + {TagType_StripOffsets, DataType_Long, []uint32{8}}, + {TagType_SamplesPerPixel, DataType_Short, []uint32{samplesPerPixel}}, + {TagType_RowsPerStrip, DataType_Short, []uint32{uint32(d.Y)}}, + {TagType_StripByteCounts, DataType_Long, []uint32{uint32(imageLen)}}, + // There is currently no support for storing the image + // resolution, so give a bogus value of 72x72 dpi. + {TagType_XResolution, DataType_Rational, []uint32{72, 1}}, + {TagType_YResolution, DataType_Rational, []uint32{72, 1}}, + {TagType_ResolutionUnit, DataType_Short, []uint32{uint32(TagValue_ResolutionUnitType_PerInch)}}, + } + if pr != uint32(TagValue_PredictorType_None) { + ifd = append(ifd, ifdEntry{TagType_Predictor, DataType_Short, []uint32{pr}}) + } + if len(colorMap) != 0 { + ifd = append(ifd, ifdEntry{TagType_ColorMap, DataType_Short, colorMap}) + } + if extraSamples > 0 { + ifd = append(ifd, ifdEntry{TagType_ExtraSamples, DataType_Short, []uint32{extraSamples}}) + } + + return writeIFD(w, imageLen+8, ifd) +} diff --git a/vendor/github.com/chai2010/tiff/gen.go b/vendor/github.com/chai2010/tiff/gen.go new file mode 100644 index 00000000..b306a939 --- /dev/null +++ b/vendor/github.com/chai2010/tiff/gen.go @@ -0,0 +1,7 @@ +// Copyright 2014 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:generate go run gen_helper.go + +package tiff diff --git a/vendor/github.com/chai2010/tiff/gen_helper.go b/vendor/github.com/chai2010/tiff/gen_helper.go new file mode 100644 index 00000000..d8028fd0 --- /dev/null +++ b/vendor/github.com/chai2010/tiff/gen_helper.go @@ -0,0 +1,484 @@ +// Copyright 2014 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ingore + +package main + +import ( + "bufio" + "bytes" + "fmt" + "go/format" + "io/ioutil" + "log" + "strconv" + "strings" + "text/scanner" +) + +type Type struct { + TypeName string + FileName string + FileData []byte + TypeList []string + TypeCommentMap map[string]string + TagTypeMap map[string][]string + TagNumMap map[string][]int + TagIFDMap map[string]string + TagIngoreMap map[string]bool + MapCode string +} + +func main() { + var types = []Type{ + Type{ + TypeName: "TiffType", + FileName: "tiff_types.go", + }, + Type{ + TypeName: "ImageType", + FileName: "tiff_types.go", + }, + Type{ + TypeName: "DataType", + FileName: "tiff_types.go", + }, + Type{ + TypeName: "TagType", + FileName: "tiff_types.go", + }, + + Type{ + TypeName: "TagValue_NewSubfileType", + FileName: "tiff_types.go", + }, + Type{ + TypeName: "TagValue_SubfileType", + FileName: "tiff_types.go", + }, + Type{ + TypeName: "TagValue_CompressionType", + FileName: "tiff_types.go", + }, + Type{ + TypeName: "TagValue_PhotometricType", + FileName: "tiff_types.go", + }, + Type{ + TypeName: "TagValue_PredictorType", + FileName: "tiff_types.go", + }, + Type{ + TypeName: "TagValue_ResolutionUnitType", + FileName: "tiff_types.go", + }, + Type{ + TypeName: "TagValue_SampleFormatType", + FileName: "tiff_types.go", + }, + + Type{ + TypeName: "ExifIFD_TagType", + FileName: "tiff_types.go", + }, + Type{ + TypeName: "GPSIFD_TagType", + FileName: "tiff_types.go", + }, + Type{ + TypeName: "InteroperabilityIFD_TagType", + FileName: "tiff_types.go", + }, + } + + var buf bytes.Buffer + fmt.Fprintf(&buf, ` +// Copyright 2014 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Auto generated by gen_helper.go, DO NOT EDIT!!! + +package tiff + +import ( + "fmt" + "time" +) + +`[1:]) + + for _, v := range types { + v.Init() + v.GenMapCode() + + fmt.Fprintf(&buf, "%s\n", v.MapCode) + } + + data, err := format.Source(buf.Bytes()) + if err != nil { + log.Fatal(err) + } + err = ioutil.WriteFile("z_tiff_types_string.go", data, 0644) + if err != nil { + log.Fatal(err) + } +} + +func (p *Type) Init() { + if p.TypeCommentMap == nil { + p.TypeCommentMap = make(map[string]string) + } + if p.TagTypeMap == nil { + p.TagTypeMap = make(map[string][]string) + } + if p.TagNumMap == nil { + p.TagNumMap = make(map[string][]int) + } + if p.TagIFDMap == nil { + p.TagIFDMap = make(map[string]string) + } + if p.TagIngoreMap == nil { + p.TagIngoreMap = make(map[string]bool) + } + + data, err := ioutil.ReadFile(p.FileName) + if err != nil { + log.Fatal(err) + } + p.FileData = data + + var s scanner.Scanner + s.Init(bytes.NewReader(p.FileData)) + + for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() { + if tok&scanner.ScanIdents != 0 { + if strings.HasPrefix(s.TokenText(), p.TypeName+"_") { + typeName := s.TokenText() + if _, ok := p.TypeCommentMap[typeName]; !ok { + comment, _, _ := bufio.NewReader(bytes.NewReader(p.FileData[s.Pos().Offset:])).ReadLine() + if idx := bytes.Index(comment, []byte("//")); idx >= 0 { + comment = comment[idx:] + } else { + comment = nil + } + p.TypeList = append(p.TypeList, typeName) + p.TypeCommentMap[typeName] = string(comment) + } + } + } + } + if p.TypeName == "TagType" { + p.parseTagComment() + } +} + +func (p *Type) parseTagComment() { + if p.TypeName != "TagType" { + return + } + // Type(A/B/C/*), Num(1/*), Required, # comment + for typeName, comment := range p.TypeCommentMap { + if strings.HasPrefix(comment, "//") { + comment = strings.TrimSpace(comment[len("//"):]) + } + if idx := strings.Index(comment, "#"); idx >= 0 { + comment = comment[:idx] + } + comment = strings.TrimSpace(comment) + + if strings.Contains(comment, "TagType_ExifIFD") { + p.TagIFDMap[typeName] = "TagType_ExifIFD" + } + if strings.Contains(comment, "TagType_GPSIFD") { + p.TagIFDMap[typeName] = "TagType_GPSIFD" + } + if strings.Contains(comment, "TagType_InteroperabilityIFD") { + p.TagIFDMap[typeName] = "TagType_InteroperabilityIFD" + } + + if strings.Contains(comment, "ingore") { + p.TagIngoreMap[typeName] = true + continue + } + if comment == "" { + continue + } + + ss := strings.Split(comment, ",") + if len(ss) > 0 { + var types []string + for _, dataType := range strings.Split(strings.TrimSpace(ss[0]), "/") { + switch dataType { + case "BYTE": + types = append(types, "DataType_Byte") + case "ASCII": + types = append(types, "DataType_ASCII") + case "SHORT": + types = append(types, "DataType_Short") + case "LONG": + types = append(types, "DataType_Long") + case "RATIONAL": + types = append(types, "DataType_Rational") + case "SBYTE": + types = append(types, "DataType_SByte") + case "UNDEFINED": + types = append(types, "DataType_Undefined") + case "SSHORT": + types = append(types, "DataType_SShort") + case "SLONG": + types = append(types, "DataType_SLong") + case "SRATIONAL": + types = append(types, "DataType_SRational") + case "FLOAT": + types = append(types, "DataType_Float") + case "DOUBLE": + types = append(types, "DataType_Double") + case "IFD": + types = append(types, "DataType_IFD") + case "UNICODE": + types = append(types, "DataType_Unicode") + case "COMPLEX": + types = append(types, "DataType_Complex") + case "LONG8": + types = append(types, "DataType_Long8") + case "SLONG8": + types = append(types, "DataType_SLong8") + case "IFD8": + types = append(types, "DataType_IFD8") + } + } + p.TagTypeMap[typeName] = types + } + if len(ss) > 1 { + var nums []int + for _, numName := range strings.Split(strings.TrimSpace(ss[1]), "/") { + if v, err := strconv.Atoi(numName); err == nil { + nums = append(nums, v) + } + } + p.TagNumMap[typeName] = nums + } + } +} + +func (p *Type) GenMapCode() { + var buf bytes.Buffer + fmt.Fprintf(&buf, "var _%sTable = map[%s]string {\n", p.TypeName, p.TypeName) + for _, s := range p.TypeList { + if _, ok := p.TagIFDMap[s]; ok { + continue + } + fmt.Fprintf(&buf, "\t%s: `%s`, %s\n", s, s, p.TypeCommentMap[s]) + } + fmt.Fprintf(&buf, "}\n") + + if p.TypeName == "TagType" && len(p.TagTypeMap) > 0 { + fmt.Fprintf(&buf, "\nvar _TagType_TypesTable = map[TagType][]DataType {\n") + for _, s := range p.TypeList { + if _, ok := p.TagIFDMap[s]; ok { + continue + } + if v, ok := p.TagTypeMap[s]; ok && len(v) > 0 { + fmt.Fprintf(&buf, "%s: []DataType{ ", s) + for j := 0; j < len(v); j++ { + fmt.Fprintf(&buf, `%s, `, v[j]) + } + fmt.Fprintf(&buf, "},\n") + } + } + fmt.Fprintf(&buf, "}\n") + + } + if p.TypeName == "TagType" && len(p.TagNumMap) > 0 { + fmt.Fprintf(&buf, "\nvar _TagType_NumsTable = map[TagType][]int {\n") + for _, s := range p.TypeList { + if _, ok := p.TagIFDMap[s]; ok { + continue + } + if v, ok := p.TagNumMap[s]; ok && len(v) > 0 { + fmt.Fprintf(&buf, "%s: []int{ ", s) + for j := 0; j < len(v); j++ { + fmt.Fprintf(&buf, `%d, `, v[j]) + } + fmt.Fprintf(&buf, "},\n") + } + } + fmt.Fprintf(&buf, "}\n") + } + + if p.TypeName == "TagType" { + fmt.Fprintf(&buf, "\ntype TagGetter interface {\n") + for _, s := range p.TypeList { + if _, ok := p.TagIFDMap[s]; ok { + continue + } + if _, ingore := p.TagIngoreMap[s]; !ingore { + fmt.Fprintf(&buf, "Get%s() (value %s, ok bool)\n", s[len("TagType_"):], p.getValueType(s)) + } + } + fmt.Fprintf(&buf, "\n") + fmt.Fprintf(&buf, "GetUnknown(tag TagType) (value []byte, ok bool)\n") + fmt.Fprintf(&buf, "\n") + fmt.Fprintf(&buf, "private()\n") + fmt.Fprintf(&buf, "}\n") + + fmt.Fprintf(&buf, "\ntype TagSetter interface {\n") + for _, s := range p.TypeList { + if _, ok := p.TagIFDMap[s]; ok { + continue + } + if _, ingore := p.TagIngoreMap[s]; !ingore { + fmt.Fprintf(&buf, "Set%s(value %s) (ok bool)\n", s[len("TagType_"):], p.getValueType(s)) + } + } + fmt.Fprintf(&buf, "\n") + fmt.Fprintf(&buf, "SetUnknown(tag TagType, value interface{}) (ok bool)\n") + fmt.Fprintf(&buf, "\n") + fmt.Fprintf(&buf, "private()\n") + fmt.Fprintf(&buf, "}\n") + } + + fmt.Fprintf(&buf, ` +func (p %s) String() string { + if name, ok := _%sTable[p]; ok { + return name + } + return fmt.Sprintf("%s_Unknown(%%d)", uint16(p)) +} +`, + p.TypeName, + p.TypeName, + p.TypeName, + ) + + p.MapCode = buf.String() +} + +func (p *Type) getValueType(typeName string) string { + switch typeName { + case "TagType_Compression": + return "TagValue_CompressionType" + case "TagType_PhotometricInterpretation": + return "TagValue_PhotometricType" + case "TagType_Predictor": + return "TagValue_PredictorType" + case "TagType_ResolutionUnit": + return "TagValue_ResolutionUnitType" + case "TagType_ColorMap": + return "[][3]uint16" + case "TagType_SMinSampleValue", "TagType_SMaxSampleValue": + return "[]float64" + case "TagType_DateTime": + return "time.Time" + } + switch types, _ := p.TagTypeMap[typeName]; { + case p.isIntType(types): + if p.isOnlyOneValue(p.TagNumMap[typeName]) { + return `int64` + } else { + return `[]int64` + } + case p.isFloatType(types): + if p.isOnlyOneValue(p.TagNumMap[typeName]) { + return `float64` + } else { + return `[]float64` + } + case p.isRationalType(types): + if p.isOnlyOneValue(p.TagNumMap[typeName]) { + return `[2]int64` + } else { + return `[][2]int64` + } + case p.isComplexType(types): + if p.isOnlyOneValue(p.TagNumMap[typeName]) { + return `complex128` + } else { + return `[]complex128` + } + case p.isStringType(types): + return `string` + case p.isUndefinedType(types): + return `[]byte` + default: + return `[]byte` + } +} + +func (p *Type) isOnlyOneValue(nums []int) bool { + return len(nums) == 1 && nums[0] == 1 +} + +func (p *Type) isIntType(dataTypes []string) bool { + if len(dataTypes) == 0 { + return false + } + for _, s := range dataTypes { + switch s { + case "DataType_Byte", "DataType_Short", "DataType_Long", "DataType_Long8": + case "DataType_SByte", "DataType_SShort", "DataType_SLong", "DataType_SLong8": + case "DataType_IFD", "DataType_IFD8": + default: + return false + } + } + return true +} +func (p *Type) isFloatType(dataTypes []string) bool { + if len(dataTypes) == 0 { + return false + } + for _, s := range dataTypes { + if s != "DataType_Float" && s != "DataType_Double" { + return false + } + } + return true +} +func (p *Type) isRationalType(dataTypes []string) bool { + if len(dataTypes) == 0 { + return false + } + for _, s := range dataTypes { + if s != "DataType_Rational" && s != "DataType_SRational" { + return false + } + } + return true +} +func (p *Type) isComplexType(dataTypes []string) bool { + if len(dataTypes) == 0 { + return false + } + for _, s := range dataTypes { + if s != "DataType_Complex" { + return false + } + } + return true +} +func (p *Type) isStringType(dataTypes []string) bool { + if len(dataTypes) == 0 { + return false + } + for _, s := range dataTypes { + if s != "DataType_ASCII" && s != "DataType_Unicode" { + return false + } + } + return true +} +func (p *Type) isUndefinedType(dataTypes []string) bool { + if len(dataTypes) == 0 { + return true + } + for _, s := range dataTypes { + if s == "DataType_Undefined" { + return true + } + } + return false +} diff --git a/vendor/github.com/chai2010/tiff/header.go b/vendor/github.com/chai2010/tiff/header.go new file mode 100644 index 00000000..360d99d9 --- /dev/null +++ b/vendor/github.com/chai2010/tiff/header.go @@ -0,0 +1,173 @@ +// Copyright 2014 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tiff + +import ( + "encoding/binary" + "fmt" + "io" + "math" +) + +type Header struct { + ByteOrder binary.ByteOrder + TiffType TiffType + FirstIFD int64 +} + +func NewHeader(isBigTiff bool, firstIFD int64) *Header { + if isBigTiff { + return &Header{ + ByteOrder: binary.LittleEndian, + TiffType: TiffType_BigTIFF, + FirstIFD: firstIFD, + } + } else { + return &Header{ + ByteOrder: binary.LittleEndian, + TiffType: TiffType_ClassicTIFF, + FirstIFD: firstIFD, + } + } +} + +func ReadHeader(r io.Reader) (header *Header, err error) { + var rs io.ReadSeeker + if rs, _ = r.(io.ReadSeeker); rs == nil { + seekReader := openSeekioReader(r, 0) + defer seekReader.Close() + rs = seekReader + } + if _, err = rs.Seek(0, 0); err != nil { + return + } + + // read classic TIFF header + var data [8]byte + if _, err = rs.Read(data[:8]); err != nil { + return + } + header = new(Header) + + // byte order + switch { + case data[0] == 'I' && data[1] == 'I': + header.ByteOrder = binary.LittleEndian + case data[0] == 'M' && data[1] == 'M': + header.ByteOrder = binary.BigEndian + default: + err = fmt.Errorf("tiff: ReadHeader, bad order: %v", data[:2]) + return + } + + // version: ClassicTIFF or BigTIFF + header.TiffType = TiffType(header.ByteOrder.Uint16(data[2:4])) + if v := header.TiffType; v != TiffType_ClassicTIFF && v != TiffType_BigTIFF { + err = fmt.Errorf("tiff: ReadHeader, bad version: %v", v) + return + } + + // offset + switch header.TiffType { + case TiffType_ClassicTIFF: + header.FirstIFD = int64(header.ByteOrder.Uint32(data[4:8])) + case TiffType_BigTIFF: + byte46 := header.ByteOrder.Uint16(data[4:6]) + byte68 := header.ByteOrder.Uint16(data[6:8]) + if byte46 != 8 || byte68 != 0 { + err = fmt.Errorf("tiff: ReadHeader, bad offset: %v", data[4:8]) + return + } + if _, err = rs.Read(data[:8]); err != nil { + return + } + header.FirstIFD = int64(header.ByteOrder.Uint64(data[0:8])) + } + if header.FirstIFD < int64(header.HeadSize()) { + err = fmt.Errorf("tiff: ReadHeader, bad offset: %v", data[4:8]) + return + } + + return +} + +func (p *Header) Bytes() []byte { + if !p.Valid() { + return nil + } + + var d [16]byte + switch p.ByteOrder { + case binary.LittleEndian: + d[0], d[1] = 'I', 'I' + case binary.BigEndian: + d[0], d[1] = 'M', 'M' + } + + if p.TiffType == TiffType_ClassicTIFF { + p.ByteOrder.PutUint16(d[2:4], uint16(p.TiffType)) + p.ByteOrder.PutUint32(d[4:8], uint32(p.FirstIFD)) + return d[:16] + } else { + p.ByteOrder.PutUint16(d[2:4], uint16(p.TiffType)) + p.ByteOrder.PutUint16(d[4:6], 8) + p.ByteOrder.PutUint16(d[6:8], 0) + p.ByteOrder.PutUint64(d[8:], uint64(p.FirstIFD)) + return d[:16] + } +} + +func (p *Header) Valid() bool { + if p == nil { + return false + } + if x := p.ByteOrder; x != binary.LittleEndian && x != binary.BigEndian { + return false + } + if !p.TiffType.Valid() { + return false + } + if p.FirstIFD < int64(p.HeadSize()) { + return false + } + if p.TiffType == TiffType_ClassicTIFF { + if p.FirstIFD > math.MaxUint32 { + return false + } + } + return true +} + +func (p *Header) HeadSize() int { + if p.TiffType == TiffType_ClassicTIFF { + return 8 + } + if p.TiffType == TiffType_BigTIFF { + return 16 + } + return 0 +} + +func (p *Header) IsBigTiff() bool { + return p.TiffType == TiffType_BigTIFF +} + +func (p *Header) String() string { + orderName := "Unknown" + switch p.ByteOrder { + case binary.LittleEndian: + orderName = "LittleEndian" + case binary.BigEndian: + orderName = "BigEndian" + } + return fmt.Sprintf( + `tiff.Header{ + ByteOrder: %s, + TiffType: %v, + Offset: %#08x, +}`, + orderName, p.TiffType, p.FirstIFD, + ) +} diff --git a/vendor/github.com/chai2010/tiff/hello.go b/vendor/github.com/chai2010/tiff/hello.go new file mode 100644 index 00000000..6765e4ca --- /dev/null +++ b/vendor/github.com/chai2010/tiff/hello.go @@ -0,0 +1,60 @@ +// Copyright 2014 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ingore + +package main + +import ( + "bytes" + "fmt" + "io/ioutil" + "log" + "os" + "path/filepath" + + tiff "github.com/chai2010/tiff" +) + +var files = []string{ + "./testdata/BigTIFFSamples/BigTIFFSubIFD8.tif", + "./testdata/multipage/multipage-gopher.tif", +} + +func main() { + for _, name := range files { + // Load file data + f, err := os.Open(name) + if err != nil { + log.Fatal(err) + } + defer f.Close() + + // Decode tiff + m, errors, err := tiff.DecodeAll(f) + if err != nil { + log.Println(err) + } + + // Encode tiff + for i := 0; i < len(m); i++ { + for j := 0; j < len(m[i]); j++ { + newname := fmt.Sprintf("%s-%02d-%02d.tiff", filepath.Base(name), i, j) + if errors[i][j] != nil { + log.Printf("%s: %v\n", newname, err) + continue + } + + var buf bytes.Buffer + if err = tiff.Encode(&buf, m[i][j], nil); err != nil { + log.Fatal(err) + } + if err = ioutil.WriteFile(newname, buf.Bytes(), 0666); err != nil { + log.Fatal(err) + } + fmt.Printf("Save %s ok\n", newname) + } + } + } +} diff --git a/vendor/github.com/chai2010/tiff/image.go b/vendor/github.com/chai2010/tiff/image.go new file mode 100644 index 00000000..94cb588a --- /dev/null +++ b/vendor/github.com/chai2010/tiff/image.go @@ -0,0 +1,448 @@ +// Copyright 2015 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tiff + +import ( + "image" + "image/color" + "reflect" + "runtime" + "unsafe" +) + +const ( + MemPMagic = "MemP" // See https://github.com/chai2010/image +) + +const ( + isLittleEndian = (runtime.GOARCH == "386" || + runtime.GOARCH == "amd64" || + runtime.GOARCH == "arm" || + runtime.GOARCH == "arm64") +) + +var ( + _ image.Image = (*MemPImage)(nil) + _ MemP = (*MemPImage)(nil) +) + +// MemP Image Spec (Native Endian), see https://github.com/chai2010/image. +type MemP interface { + MemPMagic() string + Bounds() image.Rectangle + Channels() int + DataType() reflect.Kind + Pix() []byte // PixSlice type + + // Stride is the Pix stride (in bytes, must align with SizeofKind(p.DataType)) + // between vertically adjacent pixels. + Stride() int +} + +type MemPImage struct { + XMemPMagic string // MemP + XRect image.Rectangle + XChannels int + XDataType reflect.Kind + XPix PixSlice + XStride int +} + +func NewMemPImage(r image.Rectangle, channels int, dataType reflect.Kind) *MemPImage { + m := &MemPImage{ + XMemPMagic: MemPMagic, + XRect: r, + XStride: r.Dx() * channels * SizeofKind(dataType), + XChannels: channels, + XDataType: dataType, + } + m.XPix = make([]byte, r.Dy()*m.XStride) + return m +} + +// m is MemP or image.Image +func AsMemPImage(m interface{}) (p *MemPImage, ok bool) { + if m, ok := m.(*MemPImage); ok { + return m, true + } + if m, ok := m.(MemP); ok { + return &MemPImage{ + XMemPMagic: MemPMagic, + XRect: m.Bounds(), + XChannels: m.Channels(), + XDataType: m.DataType(), + XPix: m.Pix(), + XStride: m.Stride(), + }, true + } + if m, ok := m.(*image.Gray); ok { + return &MemPImage{ + XMemPMagic: MemPMagic, + XRect: m.Bounds(), + XChannels: 1, + XDataType: reflect.Uint8, + XPix: m.Pix, + XStride: m.Stride, + }, true + } + if m, ok := m.(*image.RGBA); ok { + return &MemPImage{ + XMemPMagic: MemPMagic, + XRect: m.Bounds(), + XChannels: 4, + XDataType: reflect.Uint8, + XPix: m.Pix, + XStride: m.Stride, + }, true + } + return nil, false +} + +func NewMemPImageFrom(m image.Image) *MemPImage { + if p, ok := m.(*MemPImage); ok { + return p.Clone() + } + if p, ok := AsMemPImage(m); ok { + return p.Clone() + } + + switch m := m.(type) { + case *image.Gray: + b := m.Bounds() + p := NewMemPImage(b, 1, reflect.Uint8) + + for y := b.Min.Y; y < b.Max.Y; y++ { + off0 := m.PixOffset(0, y) + off1 := p.PixOffset(0, y) + copy(p.XPix[off1:][:p.XStride], m.Pix[off0:][:m.Stride]) + off0 += m.Stride + off1 += p.XStride + } + return p + + case *image.Gray16: + b := m.Bounds() + p := NewMemPImage(b, 1, reflect.Uint16) + + for y := b.Min.Y; y < b.Max.Y; y++ { + off0 := m.PixOffset(0, y) + off1 := p.PixOffset(0, y) + copy(p.XPix[off1:][:p.XStride], m.Pix[off0:][:m.Stride]) + off0 += m.Stride + off1 += p.XStride + } + if isLittleEndian { + p.XPix.SwapEndian(p.XDataType) + } + return p + + case *image.RGBA: + b := m.Bounds() + p := NewMemPImage(b, 4, reflect.Uint8) + + for y := b.Min.Y; y < b.Max.Y; y++ { + off0 := m.PixOffset(0, y) + off1 := p.PixOffset(0, y) + copy(p.XPix[off1:][:p.XStride], m.Pix[off0:][:m.Stride]) + off0 += m.Stride + off1 += p.XStride + } + return p + + case *image.RGBA64: + b := m.Bounds() + p := NewMemPImage(b, 4, reflect.Uint16) + + for y := b.Min.Y; y < b.Max.Y; y++ { + off0 := m.PixOffset(0, y) + off1 := p.PixOffset(0, y) + copy(p.XPix[off1:][:p.XStride], m.Pix[off0:][:m.Stride]) + off0 += m.Stride + off1 += p.XStride + } + if isLittleEndian { + p.XPix.SwapEndian(p.XDataType) + } + return p + + case *image.YCbCr: + b := m.Bounds() + p := NewMemPImage(b, 4, reflect.Uint8) + for y := b.Min.Y; y < b.Max.Y; y++ { + for x := b.Min.X; x < b.Max.X; x++ { + R, G, B, A := m.At(x, y).RGBA() + + i := p.PixOffset(x, y) + p.XPix[i+0] = uint8(R >> 8) + p.XPix[i+1] = uint8(G >> 8) + p.XPix[i+2] = uint8(B >> 8) + p.XPix[i+3] = uint8(A >> 8) + } + } + return p + + default: + b := m.Bounds() + p := NewMemPImage(b, 4, reflect.Uint16) + for y := b.Min.Y; y < b.Max.Y; y++ { + for x := b.Min.X; x < b.Max.X; x++ { + R, G, B, A := m.At(x, y).RGBA() + + i := p.PixOffset(x, y) + p.XPix[i+0] = uint8(R >> 8) + p.XPix[i+1] = uint8(R) + p.XPix[i+2] = uint8(G >> 8) + p.XPix[i+3] = uint8(G) + p.XPix[i+4] = uint8(B >> 8) + p.XPix[i+5] = uint8(B) + p.XPix[i+6] = uint8(A >> 8) + p.XPix[i+7] = uint8(A) + } + } + return p + } +} + +func (p *MemPImage) Clone() *MemPImage { + q := new(MemPImage) + *q = *p + q.XPix = append([]byte(nil), p.XPix...) + return q +} + +func (p *MemPImage) MemPMagic() string { + return p.XMemPMagic +} + +func (p *MemPImage) Bounds() image.Rectangle { + return p.XRect +} + +func (p *MemPImage) Channels() int { + return p.XChannels +} + +func (p *MemPImage) DataType() reflect.Kind { + return p.XDataType +} + +func (p *MemPImage) Pix() []byte { + return p.XPix +} + +func (p *MemPImage) Stride() int { + return p.XStride +} + +func (p *MemPImage) ColorModel() color.Model { + return ColorModel(p.XChannels, p.XDataType) +} + +func (p *MemPImage) At(x, y int) color.Color { + if !(image.Point{x, y}.In(p.XRect)) { + return MemPColor{ + Channels: p.XChannels, + DataType: p.XDataType, + } + } + i := p.PixOffset(x, y) + n := SizeofPixel(p.XChannels, p.XDataType) + return MemPColor{ + Channels: p.XChannels, + DataType: p.XDataType, + Pix: p.XPix[i:][:n], + } +} + +func (p *MemPImage) PixelAt(x, y int) []byte { + if !(image.Point{x, y}.In(p.XRect)) { + return nil + } + i := p.PixOffset(x, y) + n := SizeofPixel(p.XChannels, p.XDataType) + return p.XPix[i:][:n] +} + +func (p *MemPImage) Set(x, y int, c color.Color) { + if !(image.Point{x, y}.In(p.XRect)) { + return + } + i := p.PixOffset(x, y) + n := SizeofPixel(p.XChannels, p.XDataType) + v := p.ColorModel().Convert(c).(MemPColor) + copy(p.XPix[i:][:n], v.Pix) +} + +func (p *MemPImage) SetPixel(x, y int, c []byte) { + if !(image.Point{x, y}.In(p.XRect)) { + return + } + i := p.PixOffset(x, y) + n := SizeofPixel(p.XChannels, p.XDataType) + copy(p.XPix[i:][:n], c) +} + +func (p *MemPImage) PixOffset(x, y int) int { + return (y-p.XRect.Min.Y)*p.XStride + (x-p.XRect.Min.X)*SizeofPixel(p.XChannels, p.XDataType) +} + +func (p *MemPImage) SubImage(r image.Rectangle) image.Image { + r = r.Intersect(p.XRect) + // If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside + // either r1 or r2 if the intersection is empty. Without explicitly checking for + // this, the Pix[i:] expression below can panic. + if r.Empty() { + return &MemPImage{} + } + i := p.PixOffset(r.Min.X, r.Min.Y) + return &MemPImage{ + XRect: r, + XChannels: p.XChannels, + XDataType: p.XDataType, + XPix: p.XPix[i:], + XStride: p.XStride, + } +} + +func (p *MemPImage) AsStdImage() (m image.Image, ok bool) { + switch { + case p.XChannels == 1 && p.XDataType == reflect.Uint8: + return &image.Gray{ + Pix: p.XPix, + Stride: p.XStride, + Rect: p.XRect, + }, true + case p.XChannels == 4 && p.XDataType == reflect.Uint8: + return &image.RGBA{ + Pix: p.XPix, + Stride: p.XStride, + Rect: p.XRect, + }, true + default: + return nil, false + } +} + +func (p *MemPImage) StdImage() image.Image { + switch { + case p.XChannels == 1 && p.XDataType == reflect.Uint8: + return &image.Gray{ + Pix: p.XPix, + Stride: p.XStride, + Rect: p.XRect, + } + case p.XChannels == 1 && p.XDataType == reflect.Uint16: + m := &image.Gray16{ + Pix: p.XPix, + Stride: p.XStride, + Rect: p.XRect, + } + if isLittleEndian { + m.Pix = append([]byte(nil), m.Pix...) + PixSlice(m.Pix).SwapEndian(p.XDataType) + } + return m + case p.XChannels == 4 && p.XDataType == reflect.Uint8: + return &image.RGBA{ + Pix: p.XPix, + Stride: p.XStride, + Rect: p.XRect, + } + case p.XChannels == 4 && p.XDataType == reflect.Uint16: + m := &image.RGBA64{ + Pix: p.XPix, + Stride: p.XStride, + Rect: p.XRect, + } + if isLittleEndian { + m.Pix = append([]byte(nil), m.Pix...) + PixSlice(m.Pix).SwapEndian(p.XDataType) + } + return m + } + + return p +} + +func ChannelsOf(m image.Image) int { + if m, ok := AsMemPImage(m); ok { + return m.XChannels + } + switch m.(type) { + case *image.Gray: + return 1 + case *image.Gray16: + return 1 + case *image.YCbCr: + return 3 + } + return 4 +} + +func DepthOf(m image.Image) int { + if m, ok := m.(*MemPImage); ok { + return SizeofKind(m.XDataType) * 8 + } + if m, ok := m.(MemP); ok { + return SizeofKind(m.DataType() * 8) + } + switch m.(type) { + case *image.Gray: + return 1 * 8 + case *image.Gray16: + return 2 * 8 + case *image.NRGBA: + return 1 * 8 + case *image.NRGBA64: + return 2 * 8 + case *image.RGBA: + return 1 * 8 + case *image.RGBA64: + return 2 * 8 + case *image.YCbCr: + return 1 * 8 + } + return 2 * 8 +} + +type SizeofImager interface { + SizeofImage() int +} + +func SizeofImage(m image.Image) int { + if m, ok := m.(SizeofImager); ok { + return m.SizeofImage() + } + if m, ok := AsMemPImage(m); ok { + return int(unsafe.Sizeof(*m)) + len(m.XPix) + } + + b := m.Bounds() + switch m := m.(type) { + case *image.Alpha: + return int(unsafe.Sizeof(*m)) + b.Dx()*b.Dy()*1 + case *image.Alpha16: + return int(unsafe.Sizeof(*m)) + b.Dx()*b.Dy()*2 + case *image.Gray: + return int(unsafe.Sizeof(*m)) + b.Dx()*b.Dy()*1 + case *image.Gray16: + return int(unsafe.Sizeof(*m)) + b.Dx()*b.Dy()*2 + case *image.NRGBA: + return int(unsafe.Sizeof(*m)) + b.Dx()*b.Dy()*4 + case *image.NRGBA64: + return int(unsafe.Sizeof(*m)) + b.Dx()*b.Dy()*8 + case *image.RGBA: + return int(unsafe.Sizeof(*m)) + b.Dx()*b.Dy()*4 + case *image.RGBA64: + return int(unsafe.Sizeof(*m)) + b.Dx()*b.Dy()*8 + case *image.Uniform: + return int(unsafe.Sizeof(*m)) + case *image.YCbCr: + return int(unsafe.Sizeof(*m)) + len(m.Y) + len(m.Cb) + len(m.Cr) + } + + // return same as RGBA64 size + return int(unsafe.Sizeof((*image.RGBA64)(nil))) + b.Dx()*b.Dy()*8 +} diff --git a/vendor/github.com/chai2010/tiff/image_color.go b/vendor/github.com/chai2010/tiff/image_color.go new file mode 100644 index 00000000..4855329c --- /dev/null +++ b/vendor/github.com/chai2010/tiff/image_color.go @@ -0,0 +1,253 @@ +// Copyright 2014 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tiff + +import ( + "image/color" + "reflect" +) + +type MemPColor struct { + Channels int + DataType reflect.Kind + Pix PixSlice +} + +func (c MemPColor) RGBA() (r, g, b, a uint32) { + if len(c.Pix) == 0 { + return + } + switch c.Channels { + case 1: + switch reflect.Kind(c.DataType) { + case reflect.Uint8: + return color.Gray{ + Y: c.Pix[0], + }.RGBA() + case reflect.Uint16: + return color.Gray16{ + Y: c.Pix.Uint16s()[0], + }.RGBA() + default: + return color.Gray16{ + Y: uint16(c.Pix.Value(0, reflect.Kind(c.DataType))), + }.RGBA() + } + case 2: + switch reflect.Kind(c.DataType) { + case reflect.Uint8: + return color.RGBA{ + R: c.Pix[0], + G: c.Pix[1], + B: 0xFF, + A: 0xFF, + }.RGBA() + case reflect.Uint16: + return color.RGBA64{ + R: c.Pix.Uint16s()[0], + G: c.Pix.Uint16s()[1], + B: 0xFFFF, + A: 0xFFFF, + }.RGBA() + default: + return color.RGBA64{ + R: uint16(c.Pix.Value(0, reflect.Kind(c.DataType))), + G: uint16(c.Pix.Value(1, reflect.Kind(c.DataType))), + B: 0xFFFF, + A: 0xFFFF, + }.RGBA() + } + case 3: + switch reflect.Kind(c.DataType) { + case reflect.Uint8: + return color.RGBA{ + R: c.Pix[0], + G: c.Pix[1], + B: c.Pix[2], + A: 0xFF, + }.RGBA() + case reflect.Uint16: + return color.RGBA64{ + R: c.Pix.Uint16s()[0], + G: c.Pix.Uint16s()[1], + B: c.Pix.Uint16s()[2], + A: 0xFFFF, + }.RGBA() + default: + return color.RGBA64{ + R: uint16(c.Pix.Value(0, reflect.Kind(c.DataType))), + G: uint16(c.Pix.Value(1, reflect.Kind(c.DataType))), + B: uint16(c.Pix.Value(2, reflect.Kind(c.DataType))), + A: 0xFFFF, + }.RGBA() + } + case 4: + switch reflect.Kind(c.DataType) { + case reflect.Uint8: + return color.RGBA{ + R: c.Pix[0], + G: c.Pix[1], + B: c.Pix[2], + A: c.Pix[3], + }.RGBA() + case reflect.Uint16: + return color.RGBA64{ + R: c.Pix.Uint16s()[0], + G: c.Pix.Uint16s()[1], + B: c.Pix.Uint16s()[2], + A: c.Pix.Uint16s()[3], + }.RGBA() + default: + return color.RGBA64{ + R: uint16(c.Pix.Value(0, reflect.Kind(c.DataType))), + G: uint16(c.Pix.Value(1, reflect.Kind(c.DataType))), + B: uint16(c.Pix.Value(2, reflect.Kind(c.DataType))), + A: uint16(c.Pix.Value(3, reflect.Kind(c.DataType))), + }.RGBA() + } + } + return +} + +type ColorModelInterface interface { + Channels() int + DataType() reflect.Kind +} + +type _ColorModelT struct { + XChannels int + XDataType reflect.Kind +} + +var ( + _ ColorModelInterface = _ColorModelT{1, reflect.Uint8} +) + +func (m _ColorModelT) Convert(c color.Color) color.Color { + return colorModelConvert(m.XChannels, m.XDataType, c) +} + +func (m _ColorModelT) Channels() int { + return m.XChannels +} +func (m _ColorModelT) DataType() reflect.Kind { + return m.XDataType +} + +func ColorModel(channels int, dataType reflect.Kind) color.Model { + return _ColorModelT{ + XChannels: channels, + XDataType: dataType, + } +} + +func colorModelConvert(channels int, dataType reflect.Kind, c color.Color) color.Color { + c2 := MemPColor{ + Channels: channels, + DataType: dataType, + Pix: make(PixSlice, channels*SizeofKind(dataType)), + } + + if c1, ok := c.(MemPColor); ok { + if c1.Channels == c2.Channels && c1.DataType == c2.DataType { + copy(c2.Pix, c1.Pix) + return c2 + } + if c1.DataType == c2.DataType { + copy(c2.Pix, c1.Pix) + return c2 + } + for i := 0; i < c1.Channels && i < c2.Channels; i++ { + c2.Pix.SetValue(i, reflect.Kind(c2.DataType), c1.Pix.Value(i, reflect.Kind(c1.DataType))) + } + return c2 + } + + switch { + case channels == 1 && reflect.Kind(dataType) == reflect.Uint8: + v := color.GrayModel.Convert(c).(color.Gray) + c2.Pix[0] = v.Y + return c2 + case channels == 1 && reflect.Kind(dataType) == reflect.Uint16: + v := color.Gray16Model.Convert(c).(color.Gray16) + c2.Pix[0] = uint8(v.Y >> 8) + c2.Pix[1] = uint8(v.Y) + return c2 + case channels == 3 && reflect.Kind(dataType) == reflect.Uint8: + r, g, b, _ := c.RGBA() + c2.Pix[0] = uint8(r >> 8) + c2.Pix[1] = uint8(g >> 8) + c2.Pix[2] = uint8(b >> 8) + return c2 + case channels == 3 && reflect.Kind(dataType) == reflect.Uint16: + r, g, b, _ := c.RGBA() + c2.Pix[0] = uint8(r >> 8) + c2.Pix[1] = uint8(r) + c2.Pix[2] = uint8(g >> 8) + c2.Pix[3] = uint8(g) + c2.Pix[4] = uint8(b >> 8) + c2.Pix[5] = uint8(b) + return c2 + case channels == 4 && reflect.Kind(dataType) == reflect.Uint8: + r, g, b, a := c.RGBA() + c2.Pix[0] = uint8(r >> 8) + c2.Pix[1] = uint8(g >> 8) + c2.Pix[2] = uint8(b >> 8) + c2.Pix[3] = uint8(a >> 8) + return c2 + case channels == 4 && reflect.Kind(dataType) == reflect.Uint16: + r, g, b, a := c.RGBA() + c2.Pix[0] = uint8(r >> 8) + c2.Pix[1] = uint8(r) + c2.Pix[2] = uint8(g >> 8) + c2.Pix[3] = uint8(g) + c2.Pix[4] = uint8(b >> 8) + c2.Pix[5] = uint8(b) + c2.Pix[6] = uint8(a >> 8) + c2.Pix[7] = uint8(a) + return c2 + } + + r, g, b, a := c.RGBA() + rgba := []uint32{r, g, b, a} + for i := 0; i < c2.Channels && i < len(rgba); i++ { + c2.Pix.SetValue(i, reflect.Kind(c2.DataType), float64(rgba[i])) + } + return c2 +} + +func SizeofKind(dataType reflect.Kind) int { + switch dataType { + case reflect.Int8: + return 1 + case reflect.Int16: + return 2 + case reflect.Int32: + return 4 + case reflect.Int64: + return 8 + case reflect.Uint8: + return 1 + case reflect.Uint16: + return 2 + case reflect.Uint32: + return 4 + case reflect.Uint64: + return 8 + case reflect.Float32: + return 4 + case reflect.Float64: + return 8 + case reflect.Complex64: + return 8 + case reflect.Complex128: + return 16 + } + return 0 +} + +func SizeofPixel(channels int, dataType reflect.Kind) int { + return channels * SizeofKind(dataType) +} diff --git a/vendor/github.com/chai2010/tiff/image_pix_slice.go b/vendor/github.com/chai2010/tiff/image_pix_slice.go new file mode 100644 index 00000000..da91d7a6 --- /dev/null +++ b/vendor/github.com/chai2010/tiff/image_pix_slice.go @@ -0,0 +1,242 @@ +// Copyright 2015 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tiff + +import ( + "reflect" + "unsafe" +) + +type PixSlice []byte + +// AsPixSlice convert a normal slice to byte slice. +// +// Convert []X to []byte: +// +// x := make([]X, xLen) +// y := AsPixSlice(x) +// +func AsPixSlice(slice interface{}) (d PixSlice) { + sv := reflect.ValueOf(slice) + h := (*reflect.SliceHeader)((unsafe.Pointer(&d))) + h.Cap = sv.Cap() * int(sv.Type().Elem().Size()) + h.Len = sv.Len() * int(sv.Type().Elem().Size()) + h.Data = sv.Pointer() + return +} + +// Slice convert a normal slice to new type slice. +// +// Convert []byte to []Y: +// x := make([]byte, xLen) +// y := PixSlice(x).Slice(reflect.TypeOf([]Y(nil))).([]Y) +// +func (d PixSlice) Slice(newSliceType reflect.Type) interface{} { + sv := reflect.ValueOf(d) + newSlice := reflect.New(newSliceType) + hdr := (*reflect.SliceHeader)(unsafe.Pointer(newSlice.Pointer())) + hdr.Cap = sv.Cap() * int(sv.Type().Elem().Size()) / int(newSliceType.Elem().Size()) + hdr.Len = sv.Len() * int(sv.Type().Elem().Size()) / int(newSliceType.Elem().Size()) + hdr.Data = uintptr(sv.Pointer()) + return newSlice.Elem().Interface() +} + +func (d PixSlice) Bytes() (v []byte) { + return d +} + +func (d PixSlice) Int8s() (v []int8) { + h0 := (*reflect.SliceHeader)(unsafe.Pointer(&d)) + h1 := (*reflect.SliceHeader)(unsafe.Pointer(&v)) + + h1.Cap = h0.Cap + h1.Len = h0.Len + h1.Data = h0.Data + return +} + +func (d PixSlice) Int16s() (v []int16) { + h0 := (*reflect.SliceHeader)(unsafe.Pointer(&d)) + h1 := (*reflect.SliceHeader)(unsafe.Pointer(&v)) + + h1.Cap = h0.Cap / 2 + h1.Len = h0.Len / 2 + h1.Data = h0.Data + return +} + +func (d PixSlice) Int32s() (v []int32) { + h0 := (*reflect.SliceHeader)(unsafe.Pointer(&d)) + h1 := (*reflect.SliceHeader)(unsafe.Pointer(&v)) + + h1.Cap = h0.Cap / 4 + h1.Len = h0.Len / 4 + h1.Data = h0.Data + return +} + +func (d PixSlice) Int64s() (v []int64) { + h0 := (*reflect.SliceHeader)(unsafe.Pointer(&d)) + h1 := (*reflect.SliceHeader)(unsafe.Pointer(&v)) + + h1.Cap = h0.Cap / 8 + h1.Len = h0.Len / 8 + h1.Data = h0.Data + return +} + +func (d PixSlice) Uint8s() []uint8 { + return d +} + +func (d PixSlice) Uint16s() (v []uint16) { + h0 := (*reflect.SliceHeader)(unsafe.Pointer(&d)) + h1 := (*reflect.SliceHeader)(unsafe.Pointer(&v)) + + h1.Cap = h0.Cap / 2 + h1.Len = h0.Len / 2 + h1.Data = h0.Data + return +} + +func (d PixSlice) Uint32s() (v []uint32) { + h0 := (*reflect.SliceHeader)(unsafe.Pointer(&d)) + h1 := (*reflect.SliceHeader)(unsafe.Pointer(&v)) + + h1.Cap = h0.Cap / 4 + h1.Len = h0.Len / 4 + h1.Data = h0.Data + return +} + +func (d PixSlice) Uint64s() (v []uint64) { + h0 := (*reflect.SliceHeader)(unsafe.Pointer(&d)) + h1 := (*reflect.SliceHeader)(unsafe.Pointer(&v)) + + h1.Cap = h0.Cap / 8 + h1.Len = h0.Len / 8 + h1.Data = h0.Data + return +} + +func (d PixSlice) Float32s() (v []float32) { + h0 := (*reflect.SliceHeader)(unsafe.Pointer(&d)) + h1 := (*reflect.SliceHeader)(unsafe.Pointer(&v)) + + h1.Cap = h0.Cap / 4 + h1.Len = h0.Len / 4 + h1.Data = h0.Data + return +} + +func (d PixSlice) Float64s() (v []float64) { + h0 := (*reflect.SliceHeader)(unsafe.Pointer(&d)) + h1 := (*reflect.SliceHeader)(unsafe.Pointer(&v)) + + h1.Cap = h0.Cap / 8 + h1.Len = h0.Len / 8 + h1.Data = h0.Data + return +} + +func (d PixSlice) Complex64s() (v []complex64) { + h0 := (*reflect.SliceHeader)(unsafe.Pointer(&d)) + h1 := (*reflect.SliceHeader)(unsafe.Pointer(&v)) + + h1.Cap = h0.Cap / 16 + h1.Len = h0.Len / 16 + h1.Data = h0.Data + return +} + +func (d PixSlice) Complex128s() (v []complex128) { + h0 := (*reflect.SliceHeader)(unsafe.Pointer(&d)) + h1 := (*reflect.SliceHeader)(unsafe.Pointer(&v)) + + h1.Cap = h0.Cap / 32 + h1.Len = h0.Len / 32 + h1.Data = h0.Data + return +} + +func (d PixSlice) Value(i int, dataType reflect.Kind) float64 { + switch dataType { + case reflect.Int8: + return float64(d.Int8s()[i]) + case reflect.Int16: + return float64(d.Int16s()[i]) + case reflect.Int32: + return float64(d.Int32s()[i]) + case reflect.Int64: + return float64(d.Int64s()[i]) + case reflect.Uint8: + return float64(d[i]) + case reflect.Uint16: + return float64(d.Uint16s()[i]) + case reflect.Uint32: + return float64(d.Uint32s()[i]) + case reflect.Uint64: + return float64(d.Uint64s()[i]) + case reflect.Float32: + return float64(d.Float32s()[i]) + case reflect.Float64: + return float64(d.Float64s()[i]) + case reflect.Complex64: + return float64(real(d.Complex64s()[i])) + case reflect.Complex128: + return float64(real(d.Complex128s()[i])) + } + return 0 +} + +func (d PixSlice) SetValue(i int, dataType reflect.Kind, v float64) { + switch dataType { + case reflect.Int8: + d.Int8s()[i] = int8(v) + case reflect.Int16: + d.Int16s()[i] = int16(v) + case reflect.Int32: + d.Int32s()[i] = int32(v) + case reflect.Int64: + d.Int64s()[i] = int64(v) + case reflect.Uint8: + d[i] = byte(v) + case reflect.Uint16: + d.Uint16s()[i] = uint16(v) + case reflect.Uint32: + d.Uint32s()[i] = uint32(v) + case reflect.Uint64: + d.Uint64s()[i] = uint64(v) + case reflect.Float32: + d.Float32s()[i] = float32(v) + case reflect.Float64: + d.Float64s()[i] = float64(v) + case reflect.Complex64: + d.Complex64s()[i] = complex(float32(v), 0) + case reflect.Complex128: + d.Complex128s()[i] = complex(float64(v), 0) + } +} + +func (d PixSlice) SwapEndian(dataType reflect.Kind) { + switch dataType { + case reflect.Int16, reflect.Uint16: + for i := 0; i+2-1 < len(d); i = i + 2 { + d[i+0], d[i+1] = d[i+1], d[i+0] + } + case reflect.Int32, reflect.Uint32, reflect.Float32, reflect.Complex64: + for i := 0; i+4-1 < len(d); i = i + 4 { + d[i+0], d[i+3] = d[i+3], d[i+0] + d[i+1], d[i+2] = d[i+2], d[i+1] + } + case reflect.Int64, reflect.Uint64, reflect.Float64, reflect.Complex128: + for i := 0; i+8-1 < len(d); i = i + 8 { + d[i+0], d[i+7] = d[i+7], d[i+0] + d[i+1], d[i+6] = d[i+6], d[i+1] + d[i+2], d[i+5] = d[i+5], d[i+2] + d[i+3], d[i+4] = d[i+4], d[i+3] + } + } +} diff --git a/vendor/github.com/chai2010/tiff/image_utils.go b/vendor/github.com/chai2010/tiff/image_utils.go new file mode 100644 index 00000000..4b331ff3 --- /dev/null +++ b/vendor/github.com/chai2010/tiff/image_utils.go @@ -0,0 +1,42 @@ +// Copyright 2015 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tiff + +import ( + "fmt" + "image" +) + +func newImageWithIFD(r image.Rectangle, ifd *IFD) (m image.Image, err error) { + switch ifd.ImageType() { + case ImageType_Bilevel, ImageType_BilevelInvert: + m = image.NewGray(r) + case ImageType_Gray, ImageType_GrayInvert: + if ifd.Depth() == 16 { + m = image.NewGray16(r) + } else { + m = image.NewGray(r) + } + case ImageType_Paletted: + m = image.NewPaletted(r, ifd.ColorMap()) + case ImageType_NRGBA: + if ifd.Depth() == 16 { + m = image.NewNRGBA64(r) + } else { + m = image.NewNRGBA(r) + } + case ImageType_RGB, ImageType_RGBA: + if ifd.Depth() == 16 { + m = image.NewRGBA64(r) + } else { + m = image.NewRGBA(r) + } + } + if m == nil { + err = fmt.Errorf("tiff: Decode, unknown format") + return + } + return +} diff --git a/vendor/github.com/chai2010/tiff/internal/fax/T-REC-T.6-198811-I!!PDF-E.pdf b/vendor/github.com/chai2010/tiff/internal/fax/T-REC-T.6-198811-I!!PDF-E.pdf new file mode 100644 index 00000000..32fa877b Binary files /dev/null and b/vendor/github.com/chai2010/tiff/internal/fax/T-REC-T.6-198811-I!!PDF-E.pdf differ diff --git a/vendor/github.com/chai2010/tiff/internal/fax/extension.go b/vendor/github.com/chai2010/tiff/internal/fax/extension.go new file mode 100644 index 00000000..94891250 --- /dev/null +++ b/vendor/github.com/chai2010/tiff/internal/fax/extension.go @@ -0,0 +1,34 @@ +package fax + +import ( + "errors" + "fmt" +) + +var uncompressedMode = errors.New("fax: uncompressed mode not supported") + +func extension(d *decoder) error { + extension := d.head >> 22 + extension &= 0x7 + handler := extensionTable[extension] + if handler == nil { + return fmt.Errorf("fax: unknown extension 0b%03b", extension) + } + if e := d.pop(10); e != nil { + return e + } + return handler(d) +} + +var extensionTable = [8]func(d *decoder) error{ + nil, + nil, + nil, + nil, + nil, + nil, + nil, + func(d *decoder) error { + return uncompressedMode + }, +} diff --git a/vendor/github.com/chai2010/tiff/internal/fax/read.go b/vendor/github.com/chai2010/tiff/internal/fax/read.go new file mode 100644 index 00000000..b1d61d2c --- /dev/null +++ b/vendor/github.com/chai2010/tiff/internal/fax/read.go @@ -0,0 +1,510 @@ +// Package fax supports CCITT Group 4 image decompression +// as described by ITU-T Recommendation T.6. +// See http://www.itu.int/rec/T-REC-T.6-198811-I + +package fax + +import ( + "errors" + "image" + "io" +) + +const ( + white = 0xFF + black = 0x00 +) + +var negativeWidth = errors.New("fax: negative width specified") + +// DecodeG4 parses a Group 4 fax image from reader. +// The width will be applied as specified and the +// (estimated) height helps memory allocation. +func DecodeG4(reader io.ByteReader, width, height int) (image.Image, error) { + if width < 0 { + return nil, negativeWidth + } + if width == 0 { + return new(image.Gray), nil + } + if height <= 0 { + height = width + } + // include imaginary first line + height++ + pixels := make([]byte, width, width*height) + for i := width - 1; i >= 0; i-- { + pixels[i] = white + } + + d := &decoder{ + reader: reader, + pixels: pixels, + width: width, + atNewLine: true, + color: white, + } + + // initiate d.head + if err := d.pop(0); err != nil { + return nil, err + } + + return d.parse() +} + +func DecodeG4Pixels(reader io.ByteReader, width, height int) ([]byte, error) { + if width < 0 { + return nil, negativeWidth + } + if width == 0 { + return nil, nil + } + if height <= 0 { + height = width + } + // include imaginary first line + height++ + pixels := make([]byte, width, width*height) + for i := width - 1; i >= 0; i-- { + pixels[i] = white + } + + d := &decoder{ + reader: reader, + pixels: pixels, + width: width, + atNewLine: true, + color: white, + } + + // initiate d.head + if err := d.pop(0); err != nil { + return nil, err + } + + return d.parsePixels() +} + +type decoder struct { + // reader is the data source + reader io.ByteReader + + // head contains the current data in the stream. + // The first upcoming bit is packed in the 32nd bit, the + // second upcoming bit in the 31st, etc. + head uint + + // bitCount is the number of bits loaded in head. + bitCount uint + + // pixels are black and white values. + pixels []byte + + // width is the line length in pixels. + width int + + // atNewLine is whether a0 is before the beginning of a line. + atNewLine bool + + // color represents the state of a0. + color byte +} + +// pop advances n bits in the stream. +// The 24-bit end-of-facsimile block exceeds all +// Huffman codes in length. +func (d *decoder) pop(n uint) error { + head := d.head + count := d.bitCount + head <<= n + count -= n + for count < 24 { + next, err := d.reader.ReadByte() + if err != nil { + return err + } + head |= uint(next) << (24 - count) + count += 8 + } + d.head = head + d.bitCount = count + return nil +} + +// paint adds n d.pixels in the specified color. +func (d *decoder) paint(n int, color byte) { + a := d.pixels + for ; n != 0; n-- { + a = append(a, color) + } + d.pixels = a +} + +func (d *decoder) parse() (result image.Image, err error) { + // parse until end-of-facsimile block: 0x001001 + for d.head&0xFE000000 != 0 && err == nil { + i := (d.head >> 28) & 0xF + err = modeTable[i](d) + } + + width := d.width + pixels := d.pixels[width:] // strip imaginary line + bounds := image.Rect(0, 0, width, len(pixels)/width) + result = &image.Gray{pixels, width, bounds} + return +} + +func (d *decoder) parsePixels() (data []byte, err error) { + // parse until end-of-facsimile block: 0x001001 + for d.head&0xFE000000 != 0 && err == nil { + i := (d.head >> 28) & 0xF + err = modeTable[i](d) + } + + data = d.pixels[d.width:] // strip imaginary line + return +} + +var modeTable = [16]func(d *decoder) error{ + func(d *decoder) error { + i := (d.head >> 25) & 7 + return modeTable2[i](d) + }, + pass, + horizontal, + horizontal, + verticalLeft1, + verticalLeft1, + verticalRight1, + verticalRight1, + vertical0, vertical0, vertical0, vertical0, + vertical0, vertical0, vertical0, vertical0, +} + +var modeTable2 = [8]func(d *decoder) error{ + nil, + extension, + verticalLeft3, + verticalRight3, + verticalLeft2, + verticalLeft2, + verticalRight2, + verticalRight2, +} + +func pass(d *decoder) error { + if e := d.pop(4); e != nil { + return e + } + + color := d.color + width := d.width + pixels := d.pixels + a := len(pixels) + lineStart := (a / width) * width + b := a - width // reference element + if !d.atNewLine { + for b != lineStart && pixels[b] != color { + b++ + } + } + for b != lineStart && pixels[b] == color { + b++ + } + // found b1 + for b != lineStart && pixels[b] != color { + b++ + } + // found b2 + + if b == lineStart { + d.atNewLine = true + d.color = white + } else { + d.atNewLine = false + } + d.paint(b-a+width, color) + return nil +} + +func vertical0(d *decoder) error { + d.vertical(0) + return d.pop(1) +} + +func verticalLeft1(d *decoder) error { + d.vertical(-1) + return d.pop(3) +} + +func verticalLeft2(d *decoder) error { + d.vertical(-2) + return d.pop(6) +} + +func verticalLeft3(d *decoder) error { + d.vertical(-3) + return d.pop(7) +} + +func verticalRight1(d *decoder) error { + d.vertical(1) + return d.pop(3) +} + +func verticalRight2(d *decoder) error { + d.vertical(2) + return d.pop(6) +} + +func verticalRight3(d *decoder) error { + d.vertical(3) + return d.pop(7) +} + +func (d *decoder) vertical(offset int) { + color := d.color + width := d.width + pixels := d.pixels + a := len(pixels) + lineStart := (a / width) * width + b := a - width // reference element + if !d.atNewLine { + for b != lineStart && pixels[b] != color { + b++ + } + } + for b != lineStart && pixels[b] == color { + b++ + } + // found b1 + + b += offset + if b >= lineStart { + b = lineStart + d.atNewLine = true + d.color = white + } else { + d.atNewLine = false + d.color = color ^ 0xFF + } + if count := b - a + width; count >= 0 { + d.paint(count, color) + } +} + +func horizontal(d *decoder) (err error) { + if err = d.pop(3); err != nil { + return + } + + color := d.color + flip := color ^ 0xFF + var rl1, rl2 int + if rl1, err = d.runLength(color); err == nil { + rl2, err = d.runLength(flip) + } + + // pixels left in the line: + remaining := d.width - (len(d.pixels) % d.width) + if rl1 > remaining { + rl1 = remaining + } + d.paint(rl1, color) + remaining -= rl1 + if rl2 >= remaining { + rl2 = remaining + d.atNewLine = true + d.color = white + } else { + d.atNewLine = false + } + d.paint(rl2, flip) + return +} + +// runLength reads the amount of pixels for a color. +func (d *decoder) runLength(color byte) (count int, err error) { + match := uint16(0xFFFF) // lookup entry + for match&0xFC0 != 0 && err == nil { + if color == black { + if d.head&0xF0000000 != 0 { + match = blackShortLookup[(d.head>>26)&0x3F] + } else if d.head&0xFE000000 != 0 { + match = blackLookup[(d.head>>19)&0x1FF] + } else { + match = sharedLookup[(d.head>>20)&0x1F] + } + } else { + if d.head&0xFE000000 != 0 { + match = whiteLookup[(d.head>>23)&0x1FF] + } else { + match = sharedLookup[(d.head>>20)&0x1F] + } + } + + err = d.pop(uint(match) >> 12) + count += int(match) & 0x0FFF + } + return +} + +// Lookup tables are used by runLength to find Huffman codes. Their index +// size is large enough to fit the longest code in the group. Shorter codes +// have duplicate entries with all possible tailing bits. +// Entries consist of two parts. The 4 most significant bits contain the +// Huffman code length in bits and the 12 least significant bits contain +// the pixel count. + +var blackShortLookup = [64]uint16{ + 0x0, 0x0, 0x0, 0x0, 0x6009, 0x6008, 0x5007, 0x5007, + 0x4006, 0x4006, 0x4006, 0x4006, 0x4005, 0x4005, 0x4005, 0x4005, + 0x3001, 0x3001, 0x3001, 0x3001, 0x3001, 0x3001, 0x3001, 0x3001, + 0x3004, 0x3004, 0x3004, 0x3004, 0x3004, 0x3004, 0x3004, 0x3004, + 0x2003, 0x2003, 0x2003, 0x2003, 0x2003, 0x2003, 0x2003, 0x2003, + 0x2003, 0x2003, 0x2003, 0x2003, 0x2003, 0x2003, 0x2003, 0x2003, + 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, + 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, 0x2002, +} + +var blackLookup = [512]uint16{ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xa012, 0xa012, 0xa012, 0xa012, 0xa012, 0xa012, 0xa012, 0xa012, + 0xc034, 0xc034, 0xd280, 0xd2c0, 0xd300, 0xd340, 0xc037, 0xc037, + 0xc038, 0xc038, 0xd500, 0xd540, 0xd580, 0xd5c0, 0xc03b, 0xc03b, + 0xc03c, 0xc03c, 0xd600, 0xd640, 0xb018, 0xb018, 0xb018, 0xb018, + 0xb019, 0xb019, 0xb019, 0xb019, 0xd680, 0xd6c0, 0xc140, 0xc140, + 0xc180, 0xc180, 0xc1c0, 0xc1c0, 0xd200, 0xd240, 0xc035, 0xc035, + 0xc036, 0xc036, 0xd380, 0xd3c0, 0xd400, 0xd440, 0xd480, 0xd4c0, + 0xa040, 0xa040, 0xa040, 0xa040, 0xa040, 0xa040, 0xa040, 0xa040, + 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, + 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, + 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, + 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, 0x800d, + 0xb017, 0xb017, 0xb017, 0xb017, 0xc032, 0xc032, 0xc033, 0xc033, + 0xc02c, 0xc02c, 0xc02d, 0xc02d, 0xc02e, 0xc02e, 0xc02f, 0xc02f, + 0xc039, 0xc039, 0xc03a, 0xc03a, 0xc03d, 0xc03d, 0xc100, 0xc100, + 0xa010, 0xa010, 0xa010, 0xa010, 0xa010, 0xa010, 0xa010, 0xa010, + 0xa011, 0xa011, 0xa011, 0xa011, 0xa011, 0xa011, 0xa011, 0xa011, + 0xc030, 0xc030, 0xc031, 0xc031, 0xc03e, 0xc03e, 0xc03f, 0xc03f, + 0xc01e, 0xc01e, 0xc01f, 0xc01f, 0xc020, 0xc020, 0xc021, 0xc021, + 0xc028, 0xc028, 0xc029, 0xc029, 0xb016, 0xb016, 0xb016, 0xb016, + 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, + 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, + 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, + 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, 0x800e, + 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, + 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, + 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, + 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, + 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, + 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, + 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, + 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, 0x700a, + 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, + 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, + 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, + 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, + 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, + 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, + 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, + 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, 0x700b, + 0x900f, 0x900f, 0x900f, 0x900f, 0x900f, 0x900f, 0x900f, 0x900f, + 0x900f, 0x900f, 0x900f, 0x900f, 0x900f, 0x900f, 0x900f, 0x900f, + 0xc080, 0xc080, 0xc0c0, 0xc0c0, 0xc01a, 0xc01a, 0xc01b, 0xc01b, + 0xc01c, 0xc01c, 0xc01d, 0xc01d, 0xb013, 0xb013, 0xb013, 0xb013, + 0xb014, 0xb014, 0xb014, 0xb014, 0xc022, 0xc022, 0xc023, 0xc023, + 0xc024, 0xc024, 0xc025, 0xc025, 0xc026, 0xc026, 0xc027, 0xc027, + 0xb015, 0xb015, 0xb015, 0xb015, 0xc02a, 0xc02a, 0xc02b, 0xc02b, + 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, 0xa000, + 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, + 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, + 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, + 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, + 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, + 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, + 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, + 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, 0x700c, +} + +var whiteLookup = [512]uint16{ + 0x0, 0x0, 0x0, 0x0, 0x801d, 0x801d, 0x801e, 0x801e, + 0x802d, 0x802d, 0x802e, 0x802e, 0x7016, 0x7016, 0x7016, 0x7016, + 0x7017, 0x7017, 0x7017, 0x7017, 0x802f, 0x802f, 0x8030, 0x8030, + 0x600d, 0x600d, 0x600d, 0x600d, 0x600d, 0x600d, 0x600d, 0x600d, + 0x7014, 0x7014, 0x7014, 0x7014, 0x8021, 0x8021, 0x8022, 0x8022, + 0x8023, 0x8023, 0x8024, 0x8024, 0x8025, 0x8025, 0x8026, 0x8026, + 0x7013, 0x7013, 0x7013, 0x7013, 0x801f, 0x801f, 0x8020, 0x8020, + 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, 0x6001, + 0x600c, 0x600c, 0x600c, 0x600c, 0x600c, 0x600c, 0x600c, 0x600c, + 0x8035, 0x8035, 0x8036, 0x8036, 0x701a, 0x701a, 0x701a, 0x701a, + 0x8027, 0x8027, 0x8028, 0x8028, 0x8029, 0x8029, 0x802a, 0x802a, + 0x802b, 0x802b, 0x802c, 0x802c, 0x7015, 0x7015, 0x7015, 0x7015, + 0x701c, 0x701c, 0x701c, 0x701c, 0x803d, 0x803d, 0x803e, 0x803e, + 0x803f, 0x803f, 0x8000, 0x8000, 0x8140, 0x8140, 0x8180, 0x8180, + 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, + 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, 0x500a, + 0x500b, 0x500b, 0x500b, 0x500b, 0x500b, 0x500b, 0x500b, 0x500b, + 0x500b, 0x500b, 0x500b, 0x500b, 0x500b, 0x500b, 0x500b, 0x500b, + 0x701b, 0x701b, 0x701b, 0x701b, 0x803b, 0x803b, 0x803c, 0x803c, + 0x95c0, 0x9600, 0x9640, 0x96c0, 0x7012, 0x7012, 0x7012, 0x7012, + 0x7018, 0x7018, 0x7018, 0x7018, 0x8031, 0x8031, 0x8032, 0x8032, + 0x8033, 0x8033, 0x8034, 0x8034, 0x7019, 0x7019, 0x7019, 0x7019, + 0x8037, 0x8037, 0x8038, 0x8038, 0x8039, 0x8039, 0x803a, 0x803a, + 0x60c0, 0x60c0, 0x60c0, 0x60c0, 0x60c0, 0x60c0, 0x60c0, 0x60c0, + 0x6680, 0x6680, 0x6680, 0x6680, 0x6680, 0x6680, 0x6680, 0x6680, + 0x81c0, 0x81c0, 0x8200, 0x8200, 0x92c0, 0x9300, 0x8280, 0x8280, + 0x8240, 0x8240, 0x9340, 0x9380, 0x93c0, 0x9400, 0x9440, 0x9480, + 0x94c0, 0x9500, 0x9540, 0x9580, 0x7100, 0x7100, 0x7100, 0x7100, + 0x4002, 0x4002, 0x4002, 0x4002, 0x4002, 0x4002, 0x4002, 0x4002, + 0x4002, 0x4002, 0x4002, 0x4002, 0x4002, 0x4002, 0x4002, 0x4002, + 0x4002, 0x4002, 0x4002, 0x4002, 0x4002, 0x4002, 0x4002, 0x4002, + 0x4002, 0x4002, 0x4002, 0x4002, 0x4002, 0x4002, 0x4002, 0x4002, + 0x4003, 0x4003, 0x4003, 0x4003, 0x4003, 0x4003, 0x4003, 0x4003, + 0x4003, 0x4003, 0x4003, 0x4003, 0x4003, 0x4003, 0x4003, 0x4003, + 0x4003, 0x4003, 0x4003, 0x4003, 0x4003, 0x4003, 0x4003, 0x4003, + 0x4003, 0x4003, 0x4003, 0x4003, 0x4003, 0x4003, 0x4003, 0x4003, + 0x5080, 0x5080, 0x5080, 0x5080, 0x5080, 0x5080, 0x5080, 0x5080, + 0x5080, 0x5080, 0x5080, 0x5080, 0x5080, 0x5080, 0x5080, 0x5080, + 0x5008, 0x5008, 0x5008, 0x5008, 0x5008, 0x5008, 0x5008, 0x5008, + 0x5008, 0x5008, 0x5008, 0x5008, 0x5008, 0x5008, 0x5008, 0x5008, + 0x5009, 0x5009, 0x5009, 0x5009, 0x5009, 0x5009, 0x5009, 0x5009, + 0x5009, 0x5009, 0x5009, 0x5009, 0x5009, 0x5009, 0x5009, 0x5009, + 0x6010, 0x6010, 0x6010, 0x6010, 0x6010, 0x6010, 0x6010, 0x6010, + 0x6011, 0x6011, 0x6011, 0x6011, 0x6011, 0x6011, 0x6011, 0x6011, + 0x4004, 0x4004, 0x4004, 0x4004, 0x4004, 0x4004, 0x4004, 0x4004, + 0x4004, 0x4004, 0x4004, 0x4004, 0x4004, 0x4004, 0x4004, 0x4004, + 0x4004, 0x4004, 0x4004, 0x4004, 0x4004, 0x4004, 0x4004, 0x4004, + 0x4004, 0x4004, 0x4004, 0x4004, 0x4004, 0x4004, 0x4004, 0x4004, + 0x4005, 0x4005, 0x4005, 0x4005, 0x4005, 0x4005, 0x4005, 0x4005, + 0x4005, 0x4005, 0x4005, 0x4005, 0x4005, 0x4005, 0x4005, 0x4005, + 0x4005, 0x4005, 0x4005, 0x4005, 0x4005, 0x4005, 0x4005, 0x4005, + 0x4005, 0x4005, 0x4005, 0x4005, 0x4005, 0x4005, 0x4005, 0x4005, + 0x600e, 0x600e, 0x600e, 0x600e, 0x600e, 0x600e, 0x600e, 0x600e, + 0x600f, 0x600f, 0x600f, 0x600f, 0x600f, 0x600f, 0x600f, 0x600f, + 0x5040, 0x5040, 0x5040, 0x5040, 0x5040, 0x5040, 0x5040, 0x5040, + 0x5040, 0x5040, 0x5040, 0x5040, 0x5040, 0x5040, 0x5040, 0x5040, + 0x4006, 0x4006, 0x4006, 0x4006, 0x4006, 0x4006, 0x4006, 0x4006, + 0x4006, 0x4006, 0x4006, 0x4006, 0x4006, 0x4006, 0x4006, 0x4006, + 0x4006, 0x4006, 0x4006, 0x4006, 0x4006, 0x4006, 0x4006, 0x4006, + 0x4006, 0x4006, 0x4006, 0x4006, 0x4006, 0x4006, 0x4006, 0x4006, + 0x4007, 0x4007, 0x4007, 0x4007, 0x4007, 0x4007, 0x4007, 0x4007, + 0x4007, 0x4007, 0x4007, 0x4007, 0x4007, 0x4007, 0x4007, 0x4007, + 0x4007, 0x4007, 0x4007, 0x4007, 0x4007, 0x4007, 0x4007, 0x4007, + 0x4007, 0x4007, 0x4007, 0x4007, 0x4007, 0x4007, 0x4007, 0x4007, +} + +var sharedLookup = [32]uint16{ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xb700, 0xb700, 0xc7c0, 0xc800, 0xc840, 0xc880, 0xc8c0, 0xc900, + 0xb740, 0xb740, 0xb780, 0xb780, 0xc940, 0xc980, 0xc9c0, 0xca00, +} diff --git a/vendor/github.com/chai2010/tiff/lzw_reader.go b/vendor/github.com/chai2010/tiff/lzw_reader.go new file mode 100644 index 00000000..fb6ab33c --- /dev/null +++ b/vendor/github.com/chai2010/tiff/lzw_reader.go @@ -0,0 +1,278 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package lzw implements the Lempel-Ziv-Welch compressed data format, +// described in T. A. Welch, ``A Technique for High-Performance Data +// Compression'', Computer, 17(6) (June 1984), pp 8-19. +// +// In particular, it implements LZW as used by the TIFF file format, including +// an "off by one" algorithmic difference when compared to standard LZW. + +package tiff + +/* +This file was branched from src/pkg/compress/lzw/reader.go in the +standard library. Differences from the original are marked with "NOTE". + +The tif_lzw.c file in the libtiff C library has this comment: + +---- +The 5.0 spec describes a different algorithm than Aldus +implements. Specifically, Aldus does code length transitions +one code earlier than should be done (for real LZW). +Earlier versions of this library implemented the correct +LZW algorithm, but emitted codes in a bit order opposite +to the TIFF spec. Thus, to maintain compatibility w/ Aldus +we interpret MSB-LSB ordered codes to be images written w/ +old versions of this library, but otherwise adhere to the +Aldus "off by one" algorithm. +---- + +The Go code doesn't read (invalid) TIFF files written by old versions of +libtiff, but the LZW algorithm in this package still differs from the one in +Go's standard package library to accomodate this "off by one" in valid TIFFs. +*/ + +import ( + "bufio" + "errors" + "fmt" + "io" +) + +// lzwOrder specifies the bit ordering in an LZW data stream. +type lzwOrder int + +const ( + // LSB means Least Significant Bits first, as used in the GIF file format. + lzwLSB lzwOrder = iota + // MSB means Most Significant Bits first, as used in the TIFF and PDF + // file formats. + lzwMSB +) + +const ( + lzwMaxWidth = 12 + lzwDecoderInvalidCode = 0xffff + lzwFlushBuffer = 1 << lzwMaxWidth +) + +// lzwDecoder is the state from which the readXxx method converts a byte +// stream into a code stream. +type lzwDecoder struct { + r io.ByteReader + bits uint32 + nBits uint + width uint + read func(*lzwDecoder) (uint16, error) // readLSB or readMSB + litWidth int // width in bits of literal codes + err error + + // The first 1<= 1<>= d.width + d.nBits -= d.width + return code, nil +} + +// readMSB returns the next code for "Most Significant Bits first" data. +func (d *lzwDecoder) readMSB() (uint16, error) { + for d.nBits < d.width { + x, err := d.r.ReadByte() + if err != nil { + return 0, err + } + d.bits |= uint32(x) << (24 - d.nBits) + d.nBits += 8 + } + code := uint16(d.bits >> (32 - d.width)) + d.bits <<= d.width + d.nBits -= d.width + return code, nil +} + +func (d *lzwDecoder) Read(b []byte) (int, error) { + for { + if len(d.toRead) > 0 { + n := copy(b, d.toRead) + d.toRead = d.toRead[n:] + return n, nil + } + if d.err != nil { + return 0, d.err + } + d.decode() + } +} + +// decode decompresses bytes from r and leaves them in d.toRead. +// read specifies how to decode bytes into codes. +// litWidth is the width in bits of literal codes. +func (d *lzwDecoder) decode() { + // Loop over the code stream, converting codes into decompressed bytes. + for { + code, err := d.read(d) + if err != nil { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + d.flush() + d.err = err + return + } + switch { + case code < d.clear: + // We have a literal code. + d.output[d.o] = uint8(code) + d.o++ + if d.last != lzwDecoderInvalidCode { + // Save what the hi code expands to. + d.suffix[d.hi] = uint8(code) + d.prefix[d.hi] = d.last + } + case code == d.clear: + d.width = 1 + uint(d.litWidth) + d.hi = d.eof + d.overflow = 1 << d.width + d.last = lzwDecoderInvalidCode + continue + case code == d.eof: + d.flush() + d.err = io.EOF + return + case code <= d.hi: + c, i := code, len(d.output)-1 + if code == d.hi { + // code == hi is a special case which expands to the last expansion + // followed by the head of the last expansion. To find the head, we walk + // the prefix chain until we find a literal code. + c = d.last + for c >= d.clear { + c = d.prefix[c] + } + d.output[i] = uint8(c) + i-- + c = d.last + } + // Copy the suffix chain into output and then write that to w. + for c >= d.clear { + d.output[i] = d.suffix[c] + i-- + c = d.prefix[c] + } + d.output[i] = uint8(c) + d.o += copy(d.output[d.o:], d.output[i:]) + if d.last != lzwDecoderInvalidCode { + // Save what the hi code expands to. + d.suffix[d.hi] = uint8(c) + d.prefix[d.hi] = d.last + } + default: + d.flush() + d.err = errors.New("lzw: invalid code") + return + } + d.last, d.hi = code, d.hi+1 + if d.hi+1 >= d.overflow { // NOTE: the "+1" is where TIFF's LZW differs from the standard algorithm. + if d.width == lzwMaxWidth { + d.last = lzwDecoderInvalidCode + } else { + d.width++ + d.overflow <<= 1 + } + } + if d.o >= lzwFlushBuffer { + d.flush() + return + } + } +} + +func (d *lzwDecoder) flush() { + d.toRead = d.output[:d.o] + d.o = 0 +} + +var lzwErrClosed = errors.New("lzw: reader/writer is closed") + +func (d *lzwDecoder) Close() error { + d.err = lzwErrClosed // in case any Reads come along + return nil +} + +// newLzwReader creates a new io.ReadCloser. +// Reads from the returned io.ReadCloser read and decompress data from r. +// If r does not also implement io.ByteReader, +// the decompressor may read more data than necessary from r. +// It is the caller's responsibility to call Close on the ReadCloser when +// finished reading. +// The number of bits to use for literal codes, litWidth, must be in the +// range [2,8] and is typically 8. It must equal the litWidth +// used during compression. +func newLzwReader(r io.Reader, order lzwOrder, litWidth int) io.ReadCloser { + d := new(lzwDecoder) + switch order { + case lzwLSB: + d.read = (*lzwDecoder).readLSB + case lzwMSB: + d.read = (*lzwDecoder).readMSB + default: + d.err = errors.New("lzw: unknown order") + return d + } + if litWidth < 2 || 8 < litWidth { + d.err = fmt.Errorf("lzw: litWidth %d out of range", litWidth) + return d + } + if br, ok := r.(io.ByteReader); ok { + d.r = br + } else { + d.r = bufio.NewReader(r) + } + d.litWidth = litWidth + d.width = 1 + uint(litWidth) + d.clear = uint16(1) << uint(litWidth) + d.eof, d.hi = d.clear+1, d.clear+1 + d.overflow = uint16(1) << d.width + d.last = lzwDecoderInvalidCode + + return d +} diff --git a/vendor/github.com/chai2010/tiff/options.go b/vendor/github.com/chai2010/tiff/options.go new file mode 100644 index 00000000..c8a76fcc --- /dev/null +++ b/vendor/github.com/chai2010/tiff/options.go @@ -0,0 +1,21 @@ +// Copyright 2014 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tiff + +type Options struct { + EntryMap map[TagType]*IFDEntry +} + +func (p *Options) TagGetter() TagGetter { + return &tifTagGetter{ + EntryMap: p.EntryMap, + } +} + +func (p *Options) TagSetter() TagSetter { + return &tifTagSetter{ + EntryMap: p.EntryMap, + } +} diff --git a/vendor/github.com/chai2010/tiff/reader.go b/vendor/github.com/chai2010/tiff/reader.go new file mode 100644 index 00000000..6f9514d2 --- /dev/null +++ b/vendor/github.com/chai2010/tiff/reader.go @@ -0,0 +1,126 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tiff + +import ( + "fmt" + "image" + "io" +) + +type Reader struct { + Reader io.ReadSeeker + Header *Header + Ifd [][]*IFD + + rs *seekioReader +} + +func OpenReader(r io.Reader) (p *Reader, err error) { + rs := openSeekioReader(r, -1) + defer func() { + if err != nil && rs != nil { + rs.Close() + } + }() + + p = &Reader{} + if p.Header, err = ReadHeader(rs); err != nil { + return + } + if !p.Header.Valid() { + err = fmt.Errorf("tiff: OpenReader, invalid header: %v", p.Header) + return + } + + for offset := p.Header.FirstIFD; offset != 0; { + var ifd *IFD + var ifdList []*IFD + + if ifd, err = ReadIFD(rs, p.Header, offset); err != nil { + return + } + ifdList = append(ifdList, ifd) + offset = ifd.NextIFD + + subIfdOffsets, _ := ifd.TagGetter().GetSubIFD() + for _, subOffset := range subIfdOffsets { + ifd, _ = ReadIFD(rs, p.Header, subOffset) + ifdList = append(ifdList, ifd) + } + p.Ifd = append(p.Ifd, ifdList) + } + + p.Reader = rs + p.rs = rs + return +} + +func (p *Reader) ImageNum() int { + return len(p.Ifd) +} +func (p *Reader) SubImageNum(i int) int { + return len(p.Ifd[i]) +} + +func (p *Reader) ImageConfig(i, j int) (image.Config, error) { + return p.Ifd[i][j].ImageConfig() +} + +func (p *Reader) ImageBlocksAcross(i, j int) int { + return p.Ifd[i][j].BlocksAcross() +} + +func (p *Reader) ImageBlocksDown(i, j int) int { + return p.Ifd[i][j].BlocksDown() +} + +func (p *Reader) ImageBlockBounds(i, j, col, row int) image.Rectangle { + return p.Ifd[i][j].BlockBounds(col, row) +} + +func (p *Reader) DecodeImage(i, j int) (m image.Image, err error) { + cfg, err := p.ImageConfig(i, j) + if err != nil { + return + } + imgRect := image.Rect(0, 0, cfg.Width, cfg.Height) + if m, err = newImageWithIFD(imgRect, p.Ifd[i][j]); err != nil { + return + } + + blocksAcross := p.ImageBlocksAcross(i, j) + blocksDown := p.ImageBlocksDown(i, j) + + for col := 0; col < blocksAcross; col++ { + for row := 0; row < blocksDown; row++ { + if err = p.Ifd[i][j].DecodeBlock(p.rs, col, row, m); err != nil { + return + } + } + } + return +} + +func (p *Reader) DecodeImageBlock(i, j, col, row int) (m image.Image, err error) { + r := p.ImageBlockBounds(i, j, col, row) + if m, err = newImageWithIFD(r, p.Ifd[i][j]); err != nil { + return + } + if err = p.Ifd[i][j].DecodeBlock(p.rs, col, row, m); err != nil { + return + } + return +} + +func (p *Reader) Close() (err error) { + if p != nil { + if p.rs != nil { + err = p.rs.Close() + } + *p = Reader{} + } + return +} diff --git a/vendor/github.com/chai2010/tiff/seekio.go b/vendor/github.com/chai2010/tiff/seekio.go new file mode 100644 index 00000000..7091a72b --- /dev/null +++ b/vendor/github.com/chai2010/tiff/seekio.go @@ -0,0 +1,170 @@ +// Copyright 2015 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package seekio provides Seeker for Readers and Writers. + +package tiff + +import ( + "io" + "io/ioutil" + "os" +) + +var ( + _ seekReadCloser = (*seekioReader)(nil) + _ seekWriteCloser = (*seekioWriter)(nil) +) + +type seekReadCloser interface { + io.Seeker + io.Reader + io.Closer +} +type seekWriteCloser interface { + io.Seeker + io.Writer + io.Closer +} + +type seekioReader struct { + r io.Reader + rs io.ReadSeeker + fp *os.File + buf []byte + off int + err error +} + +func openSeekioReader(r io.Reader, maxBufferSize int) *seekioReader { + if rs, ok := r.(io.ReadSeeker); ok { + return &seekioReader{rs: rs} + } + data, err := ioutil.ReadAll(r) + return &seekioReader{r: r, buf: data, err: err} +} + +func (p *seekioReader) Read(data []byte) (n int, err error) { + if p.err != nil { + err = p.err + return + } + if p.rs != nil { + return p.rs.Read(data) + } + if p.off >= len(p.buf) { // Note len(nil)==0 + return 0, io.EOF + } + n = copy(data, p.buf[p.off:]) + p.off += n + return +} + +func (p *seekioReader) Seek(offset int64, whence int) (ret int64, err error) { + if p.err != nil { + err = p.err + return + } + if p.rs != nil { + return p.rs.Seek(offset, whence) + } + switch whence { + case 0: + ret = 0 + case 1: + ret = int64(p.off) + case 2: + ret = int64(len(p.buf)) + default: + return int64(p.off), io.EOF + } + ret += offset + if ret >= int64(len(p.buf)) { + err = io.EOF + return + } + p.off = int(ret) + return +} + +func (p *seekioReader) Close() error { + return p.err +} + +type seekioWriter struct { + w io.Writer + ws io.WriteSeeker + fp *os.File + buf []byte + off int + err error +} + +func openSeekioWriter(w io.Writer, maxBufferSize int) (*seekioWriter, error) { + if ws, ok := w.(io.WriteSeeker); ok { + return &seekioWriter{ws: ws}, nil + } + return &seekioWriter{w: w}, nil +} + +func (p *seekioWriter) Write(data []byte) (n int, err error) { + if p.err != nil { + err = p.err + return + } + if p.ws != nil { + n, err = p.ws.Write(data) + return + } + p.grow(p.off + len(data)) + n = copy(p.buf[p.off:], data) + p.off += n + return +} + +func (p *seekioWriter) grow(n int) { + if n > cap(p.buf) { + buf := make([]byte, n, 2*cap(p.buf)+n) + copy(buf, p.buf[0:p.off]) + p.buf = buf + } +} + +func (p *seekioWriter) Seek(offset int64, whence int) (ret int64, err error) { + if p.err != nil { + err = p.err + return + } + if p.ws != nil { + return p.ws.Seek(offset, whence) + } + switch whence { + case 0: + ret = 0 + case 1: + ret = int64(p.off) + case 2: + ret = int64(len(p.buf)) + default: + return int64(p.off), io.EOF + } + ret += offset + if ret < 0 || int64(ret) != ret { + return int64(p.off), io.EOF + } + p.off = int(ret) + p.grow(p.off) + return +} + +func (p *seekioWriter) Close() error { + if p.ws != nil { + return nil + } + if _, err := p.w.Write(p.buf[:p.off]); err != nil { + return err + } + *p = seekioWriter{} + return nil +} diff --git a/vendor/github.com/chai2010/tiff/tiff_ifd.go b/vendor/github.com/chai2010/tiff/tiff_ifd.go new file mode 100644 index 00000000..c0949ab0 --- /dev/null +++ b/vendor/github.com/chai2010/tiff/tiff_ifd.go @@ -0,0 +1,235 @@ +// Copyright 2014 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tiff + +import ( + "bytes" + "encoding/binary" + "fmt" + "io" + "reflect" +) + +type IFD struct { + Header *Header + EntryMap map[TagType]*IFDEntry + ThisIFD int64 + NextIFD int64 +} + +func NewIFD(hdr *Header, width, height, depth, channels int, kind reflect.Kind) (ifd *IFD) { + return +} + +func ReadIFD(r io.Reader, h *Header, offset int64) (ifd *IFD, err error) { + var rs io.ReadSeeker + if rs, _ = r.(io.ReadSeeker); rs == nil { + seekioReader := openSeekioReader(r, 0) + defer seekioReader.Close() + rs = seekioReader + } + + if !h.Valid() { + err = fmt.Errorf("tiff: ReadIFD, invalid header: %v", h) + return + } + + if h.TiffType == TiffType_ClassicTIFF { + ifd, err = readIFD(rs, h, offset) + return + } else { + ifd, err = readIFD8(rs, h, offset) + return + } +} + +func readIFD(r io.ReadSeeker, h *Header, offset int64) (p *IFD, err error) { + if offset == 0 { + return + } + if _, err = r.Seek(offset, 0); err != nil { + return + } + + p = &IFD{ + Header: h, + EntryMap: make(map[TagType]*IFDEntry), + ThisIFD: offset, + } + + // read IFDEntry + var entryNum uint16 + if err = binary.Read(r, h.ByteOrder, &entryNum); err != nil { + return + } + for i := 0; i < int(entryNum); i++ { + var entry *IFDEntry + if entry, err = readIFDEntry(r, h); err != nil { + return + } + p.EntryMap[entry.Tag] = entry + } + var nextIfdOffset uint32 + if err = binary.Read(r, h.ByteOrder, &nextIfdOffset); err != nil { + return + } + p.NextIFD = int64(nextIfdOffset) + + // read IFDEntry Data + for _, entry := range p.EntryMap { + if entry.Data, err = readIFDEntryData(r, entry); err != nil { + return + } + } + return +} + +func readIFD8(r io.ReadSeeker, h *Header, offset int64) (p *IFD, err error) { + if offset == 0 { + return + } + if _, err = r.Seek(offset, 0); err != nil { + return + } + + p = &IFD{ + Header: h, + EntryMap: make(map[TagType]*IFDEntry), + ThisIFD: offset, + } + + // read IFDEntry + var entryNum uint64 + if err = binary.Read(r, h.ByteOrder, &entryNum); err != nil { + return + } + for i := 0; i < int(entryNum); i++ { + var entry *IFDEntry + if entry, err = readIFDEntry8(r, h); err != nil { + return + } + p.EntryMap[entry.Tag] = entry + } + var nextIfdOffset uint64 + if err = binary.Read(r, h.ByteOrder, &nextIfdOffset); err != nil { + return + } + p.NextIFD = int64(nextIfdOffset) + + // read IFDEntry8 Data + for _, entry := range p.EntryMap { + if entry.Data, err = readIFDEntry8Data(r, entry); err != nil { + return + } + } + + return +} + +func readIFDEntry(r io.ReadSeeker, h *Header) (entry *IFDEntry, err error) { + var entryTag TagType + if err = binary.Read(r, h.ByteOrder, &entryTag); err != nil { + return + } + + var entryDataType DataType + if err = binary.Read(r, h.ByteOrder, &entryDataType); err != nil { + return + } + var elemCount uint32 + if err = binary.Read(r, h.ByteOrder, &elemCount); err != nil { + return + } + var elemOffset uint32 + if err = binary.Read(r, h.ByteOrder, &elemOffset); err != nil { + return + } + + entry = &IFDEntry{ + Header: h, + Tag: entryTag, + DataType: entryDataType, + Count: int(elemCount), + Offset: int64(elemOffset), + } + return +} + +func readIFDEntry8(r io.ReadSeeker, h *Header) (entry *IFDEntry, err error) { + var entryTag TagType + if err = binary.Read(r, h.ByteOrder, &entryTag); err != nil { + return + } + + var entryDataType DataType + if err = binary.Read(r, h.ByteOrder, &entryDataType); err != nil { + return + } + var elemCount uint64 + if err = binary.Read(r, h.ByteOrder, &elemCount); err != nil { + return + } + var elemOffset uint64 + if err = binary.Read(r, h.ByteOrder, &elemOffset); err != nil { + return + } + + entry = &IFDEntry{ + Header: h, + Tag: entryTag, + DataType: entryDataType, + Count: int(elemCount), + Offset: int64(elemOffset), + } + return +} + +func readIFDEntryData(r io.ReadSeeker, entry *IFDEntry) (data []byte, err error) { + valSize := entry.DataType.ByteSize() * entry.Count + if valSize <= 4 { + var buf bytes.Buffer + var offset = uint32(entry.Offset) + binary.Write(&buf, entry.Header.ByteOrder, offset) + data = buf.Bytes() + return + } + + if entry.Offset < int64(entry.Header.HeadSize()) { + err = fmt.Errorf("tiff: readIFDEntryData, bad offset %v", entry.Offset) + return + } + if _, err = r.Seek(entry.Offset, 0); err != nil { + return + } + data = make([]byte, valSize) + if _, err = r.Read(data); err != nil { + return + } + return +} + +func readIFDEntry8Data(r io.ReadSeeker, entry *IFDEntry) (data []byte, err error) { + valSize := entry.DataType.ByteSize() * entry.Count + if valSize <= 8 { + var buf bytes.Buffer + var offset = uint64(entry.Offset) + binary.Write(&buf, entry.Header.ByteOrder, offset) + data = buf.Bytes() + return + } + + if entry.Offset < int64(entry.Header.HeadSize()) { + err = fmt.Errorf("tiff: readIFDEntryData, bad offset %v", entry.Offset) + return + } + if _, err = r.Seek(entry.Offset, 0); err != nil { + return + } + data = make([]byte, valSize) + if _, err = r.Read(data); err != nil { + return + } + return +} diff --git a/vendor/github.com/chai2010/tiff/tiff_ifd_block.go b/vendor/github.com/chai2010/tiff/tiff_ifd_block.go new file mode 100644 index 00000000..fc57d581 --- /dev/null +++ b/vendor/github.com/chai2010/tiff/tiff_ifd_block.go @@ -0,0 +1,388 @@ +// Copyright 2014 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tiff + +import ( + "fmt" + "image" + "image/color" + "io" +) + +func (p *IFD) BlocksAcross() int { + imageWidth, _ := p.TagGetter().GetImageWidth() + if imageWidth == 0 { + return 0 + } + blockWidth, _ := p.TagGetter().GetTileWidth() + if blockWidth > 0 { + return int((imageWidth + blockWidth - 1) / blockWidth) + } + return 1 +} + +func (p *IFD) BlocksDown() int { + imageHeight, _ := p.TagGetter().GetImageLength() + if imageHeight == 0 { + return 0 + } + blockHeight, _ := p.TagGetter().GetTileLength() + if blockHeight > 0 { + return int((imageHeight + blockHeight - 1) / blockHeight) + } + blockHeight, _ = p.TagGetter().GetRowsPerStrip() + if blockHeight == 0 || blockHeight > imageHeight { + blockHeight = imageHeight + } + return int((imageHeight + blockHeight - 1) / blockHeight) +} + +func (p *IFD) BlockBounds(col, row int) image.Rectangle { + blocksAcross, blocksDown := p.BlocksAcross(), p.BlocksDown() + if col < 0 || row < 0 || col >= blocksAcross || row >= blocksDown { + return image.Rectangle{} + } + + if _, ok := p.TagGetter().GetTileWidth(); ok { + blockWidth, _ := p.TagGetter().GetTileWidth() + blockHeight, _ := p.TagGetter().GetTileLength() + + blkW := blockWidth + blkH := blockHeight + + xmin := col * int(blockWidth) + ymin := row * int(blockHeight) + xmax := xmin + int(blkW) + ymax := ymin + int(blkH) + + return image.Rect(xmin, ymin, xmax, ymax) + + } else { + imageWidth, _ := p.TagGetter().GetImageWidth() + imageHeight, _ := p.TagGetter().GetImageLength() + + blockWidth := imageWidth + blockHeight, ok := p.TagGetter().GetRowsPerStrip() + if !ok || blockHeight == 0 { + blockHeight = imageHeight + } + + blkW := blockWidth + blkH := blockHeight + if row == blocksDown-1 && imageHeight%blockHeight != 0 { + blkH = imageHeight % blockHeight + } + + xmin := col * int(blockWidth) + ymin := row * int(blockHeight) + xmax := xmin + int(blkW) + ymax := ymin + int(blkH) + + return image.Rect(xmin, ymin, xmax, ymax) + } +} + +func (p *IFD) BlockOffset(col, row int) int64 { + blocksAcross, blocksDown := p.BlocksAcross(), p.BlocksDown() + if col < 0 || row < 0 || col >= blocksAcross || row >= blocksDown { + return 0 + } + if _, ok := p.TagGetter().GetTileWidth(); ok { + offsets, ok := p.TagGetter().GetTileOffsets() + if !ok || len(offsets) != blocksAcross*blocksDown { + return 0 + } + return offsets[row*blocksAcross+col] + } else { + offsets, ok := p.TagGetter().GetStripOffsets() + if !ok || len(offsets) != blocksAcross*blocksDown { + return 0 + } + return offsets[row*blocksAcross+col] + } +} + +func (p *IFD) BlockCount(col, row int) int64 { + blocksAcross, blocksDown := p.BlocksAcross(), p.BlocksDown() + if col < 0 || row < 0 || col >= blocksAcross || row >= blocksDown { + return 0 + } + if _, ok := p.TagGetter().GetTileWidth(); ok { + counts, ok := p.TagGetter().GetTileByteCounts() + if !ok || len(counts) != blocksAcross*blocksDown { + return 0 + } + return counts[row*blocksAcross+col] + } else { + counts, ok := p.TagGetter().GetStripByteCounts() + if !ok || len(counts) != blocksAcross*blocksDown { + return 0 + } + return counts[row*blocksAcross+col] + } +} + +func (p *IFD) DecodeBlock(r io.ReadSeeker, col, row int, dst image.Image) (err error) { + blocksAcross, blocksDown := p.BlocksAcross(), p.BlocksDown() + if col < 0 || row < 0 || col >= blocksAcross || row >= blocksDown { + err = fmt.Errorf("tiff: IFD.DecodeBlock, bad col/row = %d/%d", col, row) + return + } + + bounds := p.BlockBounds(col, row) + offset := p.BlockOffset(col, row) + count := p.BlockCount(col, row) + + if _, err = r.Seek(offset, 0); err != nil { + return + } + limitReader := io.LimitReader(r, count) + + var data []byte + if data, err = p.Compression().Decode(limitReader, bounds.Dx(), bounds.Dy()); err != nil { + return + } + + predictor, ok := p.TagGetter().GetPredictor() + if ok && predictor == TagValue_PredictorType_Horizontal { + if data, err = p.decodePredictor(data, bounds); err != nil { + return + } + } + + err = p.decodeBlock(data, dst, bounds) + return +} + +func (p *IFD) decodePredictor(data []byte, r image.Rectangle) (out []byte, err error) { + bpp := p.Depth() + spp := p.Channels() + + switch bpp { + case 16: + var off int + for y := r.Min.Y; y < r.Max.Y; y++ { + off += spp * 2 + for x := 0; x < (r.Dx()-1)*spp*2; x += 2 { + if off+2 > len(data) { + err = fmt.Errorf("tiff: IFD.decodePredictor, not enough pixel data") + return + } + v0 := p.Header.ByteOrder.Uint16(data[off-spp*2 : off-spp*2+2]) + v1 := p.Header.ByteOrder.Uint16(data[off : off+2]) + p.Header.ByteOrder.PutUint16(data[off:off+2], v1+v0) + off += 2 + } + } + case 8: + var off int + for y := r.Min.Y; y < r.Max.Y; y++ { + off += spp + for x := 0; x < (r.Dx()-1)*spp; x++ { + if off >= len(data) { + err = fmt.Errorf("tiff: IFD.decodePredictor, not enough pixel data") + return + } + data[off] += data[off-spp] + off++ + } + } + default: + err = fmt.Errorf("tiff: IFD.decodePredictor, bad BitsPerSample = %d", bpp) + return + } + out = data + return +} + +func (p *IFD) decodeBlock(buf []byte, dst image.Image, r image.Rectangle) (err error) { + xmin, ymin := r.Min.X, r.Min.Y + xmax, ymax := r.Max.X, r.Max.Y + + rMaxX := minInt(xmax, dst.Bounds().Max.X) + rMaxY := minInt(ymax, dst.Bounds().Max.Y) + + b := p.Bounds() + rMaxX = minInt(rMaxX, b.Max.X) + rMaxY = minInt(rMaxY, b.Max.Y) + + switch p.ImageType() { + case ImageType_Gray, ImageType_GrayInvert, ImageType_Bilevel, ImageType_BilevelInvert: + if x, bpp := p.Compression(), p.Depth(); bpp == 1 && (x == TagValue_CompressionType_G3 || x == TagValue_CompressionType_G4) { + img := dst.(*image.Gray) + for y := ymin; y < rMaxY; y++ { + min := img.PixOffset(xmin, y) + max := img.PixOffset(rMaxX, y) + off := (y - ymin) * (xmax - xmin) * 1 + for i := min; i < max; i++ { + img.Pix[i+0] = buf[off+0] + off++ + } + } + return + } + + if p.Depth() == 16 { + var off int + img := dst.(*image.Gray16) + for y := ymin; y < rMaxY; y++ { + for x := xmin; x < rMaxX; x++ { + if off+2 > len(buf) { + err = fmt.Errorf("tiff: IFD.decodeBlock, not enough pixel data") + return + } + v := p.Header.ByteOrder.Uint16(buf[off : off+2]) + off += 2 + if p.ImageType() == ImageType_GrayInvert { + v = 0xffff - v + } + img.SetGray16(x, y, color.Gray16{v}) + } + } + } else { + bpp := uint(p.Depth()) + bitReader := newBitsReader(buf) + img := dst.(*image.Gray) + max := uint32((1 << uint(p.Depth())) - 1) + for y := ymin; y < rMaxY; y++ { + for x := xmin; x < rMaxX; x++ { + v, ok := bitReader.ReadBits(bpp) + if !ok { + err = fmt.Errorf("tiff: IFD.decodeBlock, not enough pixel data") + return + } + v = v * 0xff / max + if p.ImageType() == ImageType_GrayInvert { + v = 0xff - v + } + img.SetGray(x, y, color.Gray{uint8(v)}) + } + bitReader.flushBits() + } + } + case ImageType_Paletted: + bpp := uint(p.Depth()) + bitReader := newBitsReader(buf) + img := dst.(*image.Paletted) + for y := ymin; y < rMaxY; y++ { + for x := xmin; x < rMaxX; x++ { + v, ok := bitReader.ReadBits(bpp) + if !ok { + err = fmt.Errorf("tiff: IFD.decodeBlock, not enough pixel data") + return + } + img.SetColorIndex(x, y, uint8(v)) + } + bitReader.flushBits() + } + case ImageType_RGB: + if p.Depth() == 16 { + var off int + img := dst.(*image.RGBA64) + for y := ymin; y < rMaxY; y++ { + for x := xmin; x < rMaxX; x++ { + if off+6 > len(buf) { + err = fmt.Errorf("tiff: IFD.decodeBlock, not enough pixel data") + return + } + r := p.Header.ByteOrder.Uint16(buf[off+0 : off+2]) + g := p.Header.ByteOrder.Uint16(buf[off+2 : off+4]) + b := p.Header.ByteOrder.Uint16(buf[off+4 : off+6]) + off += 6 + img.SetRGBA64(x, y, color.RGBA64{r, g, b, 0xffff}) + } + } + } else { + img := dst.(*image.RGBA) + for y := ymin; y < rMaxY; y++ { + min := img.PixOffset(xmin, y) + max := img.PixOffset(rMaxX, y) + off := (y - ymin) * (xmax - xmin) * 3 + for i := min; i < max; i += 4 { + if off+3 > len(buf) { + err = fmt.Errorf("tiff: IFD.decodeBlock, not enough pixel data") + return + } + img.Pix[i+0] = buf[off+0] + img.Pix[i+1] = buf[off+1] + img.Pix[i+2] = buf[off+2] + img.Pix[i+3] = 0xff + off += 3 + } + } + } + case ImageType_NRGBA: + if p.Depth() == 16 { + var off int + img := dst.(*image.NRGBA64) + for y := ymin; y < rMaxY; y++ { + for x := xmin; x < rMaxX; x++ { + if off+8 > len(buf) { + err = fmt.Errorf("tiff: IFD.decodeBlock, not enough pixel data") + return + } + r := p.Header.ByteOrder.Uint16(buf[off+0 : off+2]) + g := p.Header.ByteOrder.Uint16(buf[off+2 : off+4]) + b := p.Header.ByteOrder.Uint16(buf[off+4 : off+6]) + a := p.Header.ByteOrder.Uint16(buf[off+6 : off+8]) + off += 8 + img.SetNRGBA64(x, y, color.NRGBA64{r, g, b, a}) + } + } + } else { + img := dst.(*image.NRGBA) + for y := ymin; y < rMaxY; y++ { + min := img.PixOffset(xmin, y) + max := img.PixOffset(rMaxX, y) + i0, i1 := (y-ymin)*(xmax-xmin)*4, (y-ymin+1)*(xmax-xmin)*4 + if i1 > len(buf) { + err = fmt.Errorf("tiff: IFD.decodeBlock, not enough pixel data") + return + } + copy(img.Pix[min:max], buf[i0:i1]) + } + } + case ImageType_RGBA: + if p.Depth() == 16 { + var off int + img := dst.(*image.RGBA64) + for y := ymin; y < rMaxY; y++ { + for x := xmin; x < rMaxX; x++ { + if off+8 > len(buf) { + err = fmt.Errorf("tiff: IFD.decodeBlock, not enough pixel data") + return + } + r := p.Header.ByteOrder.Uint16(buf[off+0 : off+2]) + g := p.Header.ByteOrder.Uint16(buf[off+2 : off+4]) + b := p.Header.ByteOrder.Uint16(buf[off+4 : off+6]) + a := p.Header.ByteOrder.Uint16(buf[off+6 : off+8]) + off += 8 + img.SetRGBA64(x, y, color.RGBA64{r, g, b, a}) + } + } + } else { + img := dst.(*image.RGBA) + for y := ymin; y < rMaxY; y++ { + min := img.PixOffset(xmin, y) + max := img.PixOffset(rMaxX, y) + i0, i1 := (y-ymin)*(xmax-xmin)*4, (y-ymin+1)*(xmax-xmin)*4 + if i1 > len(buf) { + err = fmt.Errorf("tiff: IFD.decodeBlock, not enough pixel data") + return + } + copy(img.Pix[min:max], buf[i0:i1]) + } + } + default: + err = fmt.Errorf("tiff: IFD.decodeBlock, unknown imageType: %v", p.ImageType()) + return + } + + return +} + +func (p *IFD) EncodeBlock(w io.Writer, col, row int, dst *MemPImage) (err error) { + return +} diff --git a/vendor/github.com/chai2010/tiff/tiff_ifd_entry.go b/vendor/github.com/chai2010/tiff/tiff_ifd_entry.go new file mode 100644 index 00000000..9f60dc39 --- /dev/null +++ b/vendor/github.com/chai2010/tiff/tiff_ifd_entry.go @@ -0,0 +1,551 @@ +// Copyright 2014 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tiff + +import ( + "bytes" + "encoding/binary" + "fmt" + "strings" +) + +type IFDEntry struct { + Header *Header + Tag TagType + DataType DataType + Count int + Offset int64 + Data []byte +} + +type byIFDEntry []*IFDEntry + +func (d byIFDEntry) Len() int { return len(d) } +func (d byIFDEntry) Less(i, j int) bool { return d[i].Tag < d[j].Tag } +func (d byIFDEntry) Swap(i, j int) { d[i], d[j] = d[j], d[i] } + +func NewIFDEntry(hdr *Header, tag TagType, dataType DataType, data interface{}) (p *IFDEntry) { + p = &IFDEntry{ + Header: hdr, + Tag: tag, + DataType: dataType, + } + p.SetValue(data) + return p +} + +func (p *IFDEntry) Valid() bool { + if p == nil { + return false + } + if !p.Header.Valid() || !p.Tag.Valid() || !p.DataType.Valid() { + return false + } + if p.Count <= 0 || len(p.Data) == 0 { + return false + } + return true +} + +func (p *IFDEntry) Bytes() (entry, data []byte) { + if p.Header.TiffType == TiffType_ClassicTIFF { + var buf bytes.Buffer + binary.Write(&buf, p.Header.ByteOrder, uint16(p.Tag)) + binary.Write(&buf, p.Header.ByteOrder, uint16(p.DataType)) + binary.Write(&buf, p.Header.ByteOrder, uint32(p.Count)) + + offsetOrData := make([]byte, 4) + if len(p.Data) > 4 { + p.Header.ByteOrder.PutUint32(offsetOrData, uint32(p.Offset)) + data = p.Data + } else { + copy(offsetOrData[:], p.Data) + } + buf.Write(offsetOrData) + entry = buf.Bytes() + return + } else { + var buf bytes.Buffer + binary.Write(&buf, p.Header.ByteOrder, uint16(p.Tag)) + binary.Write(&buf, p.Header.ByteOrder, uint16(p.DataType)) + binary.Write(&buf, p.Header.ByteOrder, uint64(p.Count)) + + offsetOrData := make([]byte, 8) + if len(p.Data) > 8 { + p.Header.ByteOrder.PutUint64(offsetOrData, uint64(p.Offset)) + data = p.Data + } else { + copy(offsetOrData[:], p.Data) + } + buf.Write(offsetOrData) + entry = buf.Bytes() + return + } +} + +func (p *IFDEntry) GetInts() []int64 { + switch p.DataType { + case DataType_Byte: + dst := make([]int64, p.Count) + for i := 0; i < p.Count; i++ { + dst[i] = int64(int8(p.Data[i])) + } + return dst + case DataType_SByte: + dst := make([]int64, p.Count) + for i := 0; i < p.Count; i++ { + dst[i] = int64(uint8(p.Data[i])) + } + return dst + case DataType_Short: + r := bytes.NewReader(p.Data) + dst := make([]int64, p.Count) + for i := 0; i < p.Count; i++ { + var v uint16 + if err := binary.Read(r, p.Header.ByteOrder, &v); err != nil { + return nil + } + dst[i] = int64(v) + } + return dst + case DataType_SShort: + r := bytes.NewReader(p.Data) + dst := make([]int64, p.Count) + for i := 0; i < p.Count; i++ { + var v int16 + if err := binary.Read(r, p.Header.ByteOrder, &v); err != nil { + return nil + } + dst[i] = int64(v) + } + return dst + case DataType_Long, DataType_IFD: + r := bytes.NewReader(p.Data) + dst := make([]int64, p.Count) + for i := 0; i < p.Count; i++ { + var v uint32 + if err := binary.Read(r, p.Header.ByteOrder, &v); err != nil { + return nil + } + dst[i] = int64(v) + } + return dst + case DataType_SLong: + r := bytes.NewReader(p.Data) + dst := make([]int64, p.Count) + for i := 0; i < p.Count; i++ { + var v int32 + if err := binary.Read(r, p.Header.ByteOrder, &v); err != nil { + return nil + } + dst[i] = int64(v) + } + return dst + case DataType_Long8, DataType_IFD8: + r := bytes.NewReader(p.Data) + dst := make([]int64, p.Count) + for i := 0; i < p.Count; i++ { + var v uint64 + if err := binary.Read(r, p.Header.ByteOrder, &v); err != nil { + return nil + } + dst[i] = int64(v) + } + return dst + case DataType_SLong8: + r := bytes.NewReader(p.Data) + dst := make([]int64, p.Count) + for i := 0; i < p.Count; i++ { + var v int64 + if err := binary.Read(r, p.Header.ByteOrder, &v); err != nil { + return nil + } + dst[i] = int64(v) + } + return dst + } + return nil +} + +func (p *IFDEntry) GetFloats() []float64 { + switch p.DataType { + case DataType_Float: + r := bytes.NewReader(p.Data) + dst := make([]float64, p.Count) + for i := 0; i < p.Count; i++ { + var v float32 + if err := binary.Read(r, p.Header.ByteOrder, &v); err != nil { + return nil + } + dst[i] = float64(v) + } + return dst + case DataType_Double: + r := bytes.NewReader(p.Data) + dst := make([]float64, p.Count) + for i := 0; i < p.Count; i++ { + var v float64 + if err := binary.Read(r, p.Header.ByteOrder, &v); err != nil { + return nil + } + dst[i] = float64(v) + } + return dst + case DataType_Rational, DataType_SRational: + rats := p.GetRationals() + floats := make([]float64, len(rats)) + for i := 0; i < len(rats); i++ { + floats[i] = float64(rats[i][0]) / float64(rats[i][1]) + } + return floats + default: + ints := p.GetInts() + floats := make([]float64, len(ints)) + for i := 0; i < len(ints); i++ { + floats[i] = float64(ints[i]) + } + return floats + } +} + +func (p *IFDEntry) GetRationals() [][2]int64 { + switch p.DataType { + case DataType_Rational: + r := bytes.NewReader(p.Data) + dst := make([][2]int64, p.Count) + for i := 0; i < p.Count; i++ { + var v [2]uint32 + if err := binary.Read(r, p.Header.ByteOrder, &v); err != nil { + return nil + } + dst[i][0] = int64(v[0]) + dst[i][1] = int64(v[1]) + } + return dst + case DataType_SRational: + r := bytes.NewReader(p.Data) + dst := make([][2]int64, p.Count) + for i := 0; i < p.Count; i++ { + var v [2]int32 + if err := binary.Read(r, p.Header.ByteOrder, &v); err != nil { + return nil + } + dst[i][0] = int64(v[0]) + dst[i][1] = int64(v[1]) + } + return dst + } + return nil +} + +func (p *IFDEntry) GetString() string { + switch p.DataType { + case DataType_ASCII: + if idx := bytes.Index(p.Data, []byte("\000")); idx >= 0 { + return string(p.Data[:idx]) + } + return string(p.Data) + } + return "" +} + +func (p *IFDEntry) GetValue() interface{} { + panic("TODO") +} + +func (p *IFDEntry) GetUndefined(value interface{}) interface{} { + if p.DataType != DataType_Undefined { + return nil + } + if err := binary.Read(bytes.NewReader(p.Data), p.Header.ByteOrder, value); err != nil { + return nil + } + return value +} + +func (p *IFDEntry) SetInts(value ...int64) (err error) { + if p.DataType == DataType_Nil { + if p.Header.IsBigTiff() { + p.DataType = DataType_Long8 + } else { + p.DataType = DataType_Long + } + } + switch p.DataType { + case DataType_Byte: + tmp := make([]uint8, len(value)) + for i := 0; i < len(tmp); i++ { + tmp[i] = uint8(value[i]) + } + var buf bytes.Buffer + if err = binary.Write(&buf, p.Header.ByteOrder, tmp); err != nil { + return + } + p.Data = buf.Bytes() + p.Count = len(tmp) + case DataType_SByte: + tmp := make([]int8, len(value)) + for i := 0; i < len(tmp); i++ { + tmp[i] = int8(value[i]) + } + var buf bytes.Buffer + if err = binary.Write(&buf, p.Header.ByteOrder, tmp); err != nil { + return + } + p.Data = buf.Bytes() + p.Count = len(tmp) + case DataType_Short: + tmp := make([]uint16, len(value)) + for i := 0; i < len(tmp); i++ { + tmp[i] = uint16(value[i]) + } + var buf bytes.Buffer + if err = binary.Write(&buf, p.Header.ByteOrder, tmp); err != nil { + return + } + p.Data = buf.Bytes() + p.Count = len(tmp) + case DataType_SShort: + tmp := make([]int16, len(value)) + for i := 0; i < len(tmp); i++ { + tmp[i] = int16(value[i]) + } + var buf bytes.Buffer + if err = binary.Write(&buf, p.Header.ByteOrder, tmp); err != nil { + return + } + p.Data = buf.Bytes() + p.Count = len(tmp) + case DataType_Long, DataType_IFD: + tmp := make([]uint32, len(value)) + for i := 0; i < len(tmp); i++ { + tmp[i] = uint32(value[i]) + } + var buf bytes.Buffer + if err = binary.Write(&buf, p.Header.ByteOrder, tmp); err != nil { + return + } + p.Data = buf.Bytes() + p.Count = len(tmp) + case DataType_SLong: + tmp := make([]int32, len(value)) + for i := 0; i < len(tmp); i++ { + tmp[i] = int32(value[i]) + } + var buf bytes.Buffer + if err = binary.Write(&buf, p.Header.ByteOrder, tmp); err != nil { + return + } + p.Data = buf.Bytes() + p.Count = len(tmp) + case DataType_Long8, DataType_IFD8: + tmp := make([]uint64, len(value)) + for i := 0; i < len(tmp); i++ { + tmp[i] = uint64(value[i]) + } + var buf bytes.Buffer + if err = binary.Write(&buf, p.Header.ByteOrder, tmp); err != nil { + return + } + p.Data = buf.Bytes() + p.Count = len(tmp) + case DataType_SLong8: + tmp := make([]int64, len(value)) + for i := 0; i < len(tmp); i++ { + tmp[i] = int64(value[i]) + } + var buf bytes.Buffer + if err = binary.Write(&buf, p.Header.ByteOrder, tmp); err != nil { + return + } + p.Data = buf.Bytes() + p.Count = len(tmp) + } + return +} + +func (p *IFDEntry) SetFloats(value ...float64) (err error) { + if p.DataType == DataType_Nil { + p.DataType = DataType_Double + } + switch p.DataType { + case DataType_Float: + tmp := make([]float32, len(value)) + for i := 0; i < len(tmp); i++ { + tmp[i] = float32(value[i]) + } + + var buf bytes.Buffer + if err = binary.Write(&buf, p.Header.ByteOrder, tmp); err != nil { + return + } + p.Data = buf.Bytes() + p.Count = len(tmp) + case DataType_Double: + var buf bytes.Buffer + if err = binary.Write(&buf, p.Header.ByteOrder, value); err != nil { + return + } + p.Data = buf.Bytes() + p.Count = len(value) + } + return +} + +func (p *IFDEntry) SetRationals(value ...[2]int64) (err error) { + if p.DataType == DataType_Nil { + p.DataType = DataType_Rational + } + switch p.DataType { + case DataType_Rational: + tmp := make([][2]uint32, len(value)) + for i := 0; i < len(tmp); i++ { + tmp[i][0] = uint32(value[i][0]) + tmp[i][1] = uint32(value[i][1]) + } + + var buf bytes.Buffer + if err = binary.Write(&buf, p.Header.ByteOrder, tmp); err != nil { + return + } + p.Data = buf.Bytes() + p.Count = len(tmp) + case DataType_SRational: + tmp := make([][2]int32, len(value)) + for i := 0; i < len(tmp); i++ { + tmp[i][0] = int32(value[i][0]) + tmp[i][1] = int32(value[i][1]) + } + + var buf bytes.Buffer + if err = binary.Write(&buf, p.Header.ByteOrder, tmp); err != nil { + return + } + p.Data = buf.Bytes() + p.Count = len(tmp) + } + return +} + +func (p *IFDEntry) SetString(value string) (err error) { + if p.DataType == DataType_Nil { + p.DataType = DataType_ASCII + } + switch p.DataType { + case DataType_ASCII: + if idx := strings.Index(value, "\000"); idx >= 0 { + value = value[:idx] + } + p.Data = make([]byte, len(value)+1) + copy(p.Data, []byte(value)) + p.Data[len(value)] = 0 // +NULL + p.Count = len(p.Data) + 1 + } + return +} + +func (p *IFDEntry) SetUndefined(value interface{}) (err error) { + if p.DataType == DataType_Nil { + p.DataType = DataType_Undefined + } + if p.DataType != DataType_Undefined { + return + } + var buf bytes.Buffer + if err = binary.Write(&buf, p.Header.ByteOrder, value); err != nil { + return + } + p.Data = buf.Bytes() + p.Count = len(p.Data) + return +} + +func (p *IFDEntry) SetValue(value interface{}) (err error) { + panic("TODO") +} + +func (p *IFDEntry) isOnlyOneValue() bool { + nums, _ := _TagType_NumsTable[p.Tag] + return len(nums) == 1 && nums[0] == 1 +} + +func (p *IFDEntry) String() string { + switch p.Tag { + case TagType_NewSubfileType: + if v := p.GetInts(); len(v) == 1 { + return fmt.Sprintf("%v(%v): %v", p.Tag, p.DataType, TagValue_NewSubfileType(v[0])) + } + case TagType_SubfileType: + if v := p.GetInts(); len(v) == 1 { + return fmt.Sprintf("%v(%v): %v", p.Tag, p.DataType, TagValue_SubfileType(v[0])) + } + case TagType_ImageWidth: + if v := p.GetInts(); len(v) == 1 { + return fmt.Sprintf("%v(%v): %v", p.Tag, p.DataType, int(v[0])) + } + case TagType_ImageLength: + if v := p.GetInts(); len(v) == 1 { + return fmt.Sprintf("%v(%v): %v", p.Tag, p.DataType, int(v[0])) + } + case TagType_Compression: + if v := p.GetInts(); len(v) == 1 { + return fmt.Sprintf("%v(%v): %v", p.Tag, p.DataType, TagValue_CompressionType(v[0])) + } + case TagType_PhotometricInterpretation: + if v := p.GetInts(); len(v) == 1 { + return fmt.Sprintf("%v(%v): %v", p.Tag, p.DataType, TagValue_PhotometricType(v[0])) + } + case TagType_RowsPerStrip: + if v := p.GetInts(); len(v) == 1 { + return fmt.Sprintf("%v(%v): %v", p.Tag, p.DataType, int(v[0])) + } + case TagType_SamplesPerPixel: + if v := p.GetInts(); len(v) == 1 { + return fmt.Sprintf("%v(%v): %v", p.Tag, p.DataType, int(v[0])) + } + case TagType_ResolutionUnit: + if v := p.GetInts(); len(v) == 1 { + return fmt.Sprintf("%v(%v): %v", p.Tag, p.DataType, TagValue_ResolutionUnitType(v[0])) + } + case TagType_Predictor: + if v := p.GetInts(); len(v) == 1 { + return fmt.Sprintf("%v(%v): %v", p.Tag, p.DataType, TagValue_PredictorType(v[0])) + } + case TagType_StripOffsets, TagType_TileOffsets, TagType_FreeOffsets: + return fmt.Sprintf("%v(%v): %#08x", p.Tag, p.DataType, p.GetInts()) + case TagType_SampleFormat: + if v := p.GetInts(); len(v) == 1 { + return fmt.Sprintf("%v(%v): %v", p.Tag, p.DataType, TagValue_SampleFormatType(v[0])) + } + } + switch { + case p.DataType.IsIntType(): + switch p.DataType { + case DataType_IFD, DataType_IFD8: + return fmt.Sprintf("%v(%v): %#08x", p.Tag, p.DataType, p.GetInts()) + } + if v := p.GetInts(); len(v) == 1 && p.isOnlyOneValue() { + return fmt.Sprintf("%v(%v): %v", p.Tag, p.DataType, v[0]) + } else { + return fmt.Sprintf("%v(%v): %v", p.Tag, p.DataType, v) + } + case p.DataType.IsFloatType(): + if v := p.GetFloats(); len(v) == 1 && p.isOnlyOneValue() { + return fmt.Sprintf("%v(%v): %v", p.Tag, p.DataType, v[0]) + } else { + return fmt.Sprintf("%v(%v): %v", p.Tag, p.DataType, v) + } + case p.DataType.IsRationalType(): + if v := p.GetRationals(); len(v) == 1 && p.isOnlyOneValue() { + return fmt.Sprintf("%v(%v): %v", p.Tag, p.DataType, v[0]) + } else { + return fmt.Sprintf("%v(%v): %v", p.Tag, p.DataType, v) + } + case p.DataType.IsStringType(): + return fmt.Sprintf("%v(%v): %q", p.Tag, p.DataType, p.GetString()) + default: + return fmt.Sprintf("%v(%v): %v", p.Tag, p.DataType, p.Data) + } +} diff --git a/vendor/github.com/chai2010/tiff/tiff_ifd_helper.go b/vendor/github.com/chai2010/tiff/tiff_ifd_helper.go new file mode 100644 index 00000000..6a4572ae --- /dev/null +++ b/vendor/github.com/chai2010/tiff/tiff_ifd_helper.go @@ -0,0 +1,324 @@ +// Copyright 2014 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tiff + +import ( + "bytes" + "encoding/binary" + "fmt" + "image" + "image/color" + "sort" +) + +func (p *IFD) Valid() bool { + if p == nil { + return false + } + if !p.Header.Valid() || len(p.EntryMap) == 0 { + return false + } + return true +} + +func (p *IFD) TagGetter() TagGetter { + return &tifTagGetter{ + EntryMap: p.EntryMap, + } +} + +func (p *IFD) TagSetter() TagSetter { + return &tifTagSetter{ + EntryMap: p.EntryMap, + } +} + +func (p *IFD) Bounds() image.Rectangle { + var width, height int + if v, ok := p.TagGetter().GetImageWidth(); ok { + width = int(v) + } + if v, ok := p.TagGetter().GetImageLength(); ok { + height = int(v) + } + return image.Rect(0, 0, width, height) +} + +func (p *IFD) Depth() int { + if v, ok := p.TagGetter().GetBitsPerSample(); ok { + for i := 1; i < len(v); i++ { + if v[i] != v[0] { + return 0 + } + } + if len(v) > 0 { + return int(v[0]) + } + } + return 0 +} + +func (p *IFD) Channels() int { + if v, ok := p.TagGetter().GetBitsPerSample(); ok { + return len(v) + } + return 0 +} + +func (p *IFD) ImageType() ImageType { + var requiredTags = []TagType{ + TagType_ImageWidth, + TagType_ImageLength, + TagType_PhotometricInterpretation, + } + var requiredTiledTags = []TagType{ + TagType_TileWidth, + TagType_TileLength, + TagType_TileOffsets, + TagType_TileByteCounts, + } + var requiredStripTags = []TagType{ + TagType_RowsPerStrip, // default is (2^32-1) + TagType_StripOffsets, + TagType_StripByteCounts, + } + + var isTiled bool + for _, tag := range requiredTiledTags { + if _, ok := p.EntryMap[tag]; ok { + isTiled = true + } + } + + if isTiled { + for _, tag := range requiredTags { + if _, ok := p.EntryMap[tag]; !ok { + return ImageType_Nil + } + } + for _, tag := range requiredTiledTags { + if _, ok := p.EntryMap[tag]; !ok { + return ImageType_Nil + } + } + + } else { + for _, tag := range requiredTags { + if _, ok := p.EntryMap[tag]; !ok { + return ImageType_Nil + } + } + for _, tag := range requiredStripTags { + if _, ok := p.EntryMap[tag]; !ok { + if tag != TagType_RowsPerStrip { + return ImageType_Nil + } + } + } + } + + var ( + photometric, _ = p.TagGetter().GetPhotometricInterpretation() + bitsPerSample, _ = p.TagGetter().GetBitsPerSample() + extraSamples, hasExtraSamples = p.TagGetter().GetExtraSamples() + ) + + switch photometric { + case TagValue_PhotometricType_WhiteIsZero: + if len(bitsPerSample) == 1 && bitsPerSample[0] < 8 { + return ImageType_BilevelInvert + } else { + return ImageType_GrayInvert + } + case TagValue_PhotometricType_BlackIsZero: + if len(bitsPerSample) == 1 && bitsPerSample[0] < 8 { + return ImageType_Bilevel + } else { + return ImageType_Gray + } + case TagValue_PhotometricType_RGB: + if p.Channels() == 3 { + return ImageType_RGB + } + if p.Channels() == 4 { + if hasExtraSamples && extraSamples == 1 { + return ImageType_RGBA + } + if hasExtraSamples && extraSamples == 2 { + return ImageType_NRGBA + } + } + return ImageType_Nil + case TagValue_PhotometricType_Paletted: + return ImageType_Paletted + case TagValue_PhotometricType_TransMask: + return ImageType_Nil + case TagValue_PhotometricType_CMYK: + return ImageType_Nil + case TagValue_PhotometricType_YCbCr: + return ImageType_Nil + case TagValue_PhotometricType_CIELab: + return ImageType_Nil + } + + return ImageType_Nil +} + +func (p *IFD) ImageConfig() (config image.Config, err error) { + var ( + imageWidth, _ = p.TagGetter().GetImageWidth() + imageHeight, _ = p.TagGetter().GetImageLength() + photometric, _ = p.TagGetter().GetPhotometricInterpretation() + bitsPerSample, _ = p.TagGetter().GetBitsPerSample() + extraSamples, _ = p.TagGetter().GetExtraSamples() + ) + if len(bitsPerSample) == 0 { + err = fmt.Errorf("tiff: IFD.ColorModel, bad bitsPerSample length") + return + } + + config.Width = int(imageWidth) + config.Height = int(imageHeight) + + switch photometric { + case TagValue_PhotometricType_RGB: + if bitsPerSample[0] == 16 { + for _, b := range bitsPerSample { + if b != 16 { + err = fmt.Errorf("tiff: IFD.ColorModel, wrong number of samples for 16bit RGB") + return + } + } + } else { + for _, b := range bitsPerSample { + if b != 8 { + err = fmt.Errorf("tiff: IFD.ColorModel, wrong number of samples for 8bit RGB") + return + } + } + } + switch len(bitsPerSample) { + case 3: + if bitsPerSample[0] == 16 { + config.ColorModel = color.RGBA64Model + } else { + config.ColorModel = color.RGBAModel + } + case 4: + switch extraSamples { + case 1: + if bitsPerSample[0] == 16 { + config.ColorModel = color.RGBA64Model + } else { + config.ColorModel = color.RGBAModel + } + case 2: + if bitsPerSample[0] == 16 { + config.ColorModel = color.NRGBA64Model + } else { + config.ColorModel = color.NRGBAModel + } + default: + err = fmt.Errorf("tiff: IFD.ColorModel, wrong number of samples for RGB") + return + } + default: + err = fmt.Errorf("tiff: IFD.ColorModel, wrong number of samples for RGB") + return + } + case TagValue_PhotometricType_Paletted: + config.ColorModel = color.Palette(p.ColorMap()) + case TagValue_PhotometricType_WhiteIsZero: + if bitsPerSample[0] == 16 { + config.ColorModel = color.Gray16Model + } else { + config.ColorModel = color.GrayModel + } + case TagValue_PhotometricType_BlackIsZero: + if bitsPerSample[0] == 16 { + config.ColorModel = color.Gray16Model + } else { + config.ColorModel = color.GrayModel + } + default: + err = fmt.Errorf("tiff: decoder.Decode, unsupport color model") + return + } + return +} + +func (p *IFD) Compression() TagValue_CompressionType { + if tag, ok := p.EntryMap[TagType_Compression]; ok { + if v := tag.GetInts(); len(v) == 1 { + return TagValue_CompressionType(v[0]) + } + } + return TagValue_CompressionType_Nil +} + +func (p *IFD) ColorMap() (palette color.Palette) { + v, ok := p.TagGetter().GetColorMap() + if !ok { + return + } + palette = make([]color.Color, len(v)) + for i := 0; i < len(palette); i++ { + palette[i] = color.RGBA64{ + uint16(v[i][0]), + uint16(v[i][1]), + uint16(v[i][2]), + 0xffff, + } + } + return +} + +func (p *IFD) Bytes() []byte { + if !p.Valid() { + return nil + } + + tagList := make([]*IFDEntry, 0, len(p.EntryMap)) + for _, v := range p.EntryMap { + tagList = append(tagList, v) + } + sort.Sort(byIFDEntry(tagList)) + + var buf bytes.Buffer + if p.Header.TiffType == TiffType_ClassicTIFF { + binary.Write(&buf, p.Header.ByteOrder, uint32(len(tagList))) + for i := 0; i < len(tagList); i++ { + entryBytes, _ := tagList[i].Bytes() + buf.Write(entryBytes) + } + binary.Write(&buf, p.Header.ByteOrder, uint32(p.NextIFD)) + } else { + binary.Write(&buf, p.Header.ByteOrder, uint32(len(tagList))) + for i := 0; i < len(tagList); i++ { + entryBytes, _ := tagList[i].Bytes() + buf.Write(entryBytes) + } + binary.Write(&buf, p.Header.ByteOrder, uint32(p.NextIFD)) + } + return buf.Bytes() +} + +func (p *IFD) String() string { + var buf bytes.Buffer + fmt.Fprintf(&buf, "tiff.IFD(%#08x) {\n", p.ThisIFD) + + tagList := make([]*IFDEntry, 0, len(p.EntryMap)) + for _, v := range p.EntryMap { + tagList = append(tagList, v) + } + sort.Sort(byIFDEntry(tagList)) + + for _, v := range tagList { + fmt.Fprintf(&buf, "\t%v,\n", v) + } + fmt.Fprintf(&buf, "\tNext: %#08x,\n", p.NextIFD) + fmt.Fprintf(&buf, "}") + return buf.String() +} diff --git a/vendor/github.com/chai2010/tiff/tiff_ifd_tag_getter.go b/vendor/github.com/chai2010/tiff/tiff_ifd_tag_getter.go new file mode 100644 index 00000000..f2b8649b --- /dev/null +++ b/vendor/github.com/chai2010/tiff/tiff_ifd_tag_getter.go @@ -0,0 +1,981 @@ +// Copyright 2014 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tiff + +import ( + "fmt" + "time" +) + +var _ TagGetter = (*tifTagGetter)(nil) + +type tifTagGetter struct { + EntryMap map[TagType]*IFDEntry +} + +func (p *tifTagGetter) GetNewSubfileType() (value int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_NewSubfileType]; !ok { + value = 0 + ok = true + return + } + if v := entry.GetInts(); len(v) == 1 { + value = v[0] + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetSubfileType() (value int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_SubfileType]; !ok { + return + } + if v := entry.GetInts(); len(v) == 1 { + value = v[0] + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetImageWidth() (value int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_ImageWidth]; !ok { + return + } + if v := entry.GetInts(); len(v) == 1 { + value = v[0] + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetImageLength() (value int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_ImageLength]; !ok { + return + } + if v := entry.GetInts(); len(v) == 1 { + value = v[0] + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetBitsPerSample() (value []int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_BitsPerSample]; !ok { + value = []int64{1} // Default + ok = true + return + } + value = entry.GetInts() + return +} + +func (p *tifTagGetter) GetCompression() (value TagValue_CompressionType, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_Compression]; !ok { + value = TagValue_CompressionType_None + ok = true + return + } + if v := entry.GetInts(); len(v) == 1 { + value = TagValue_CompressionType(v[0]) + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetPhotometricInterpretation() (value TagValue_PhotometricType, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_PhotometricInterpretation]; !ok { + return + } + if v := entry.GetInts(); len(v) == 1 { + value = TagValue_PhotometricType(v[0]) + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetThreshholding() (value int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_Threshholding]; !ok { + value = 1 + ok = true + return + } + if v := entry.GetInts(); len(v) == 1 { + value = v[0] + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetCellWidth() (value int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_CellWidth]; !ok { + return + } + if v := entry.GetInts(); len(v) == 1 { + value = v[0] + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetCellLenght() (value int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_CellLenght]; !ok { + return + } + if v := entry.GetInts(); len(v) == 1 { + value = v[0] + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetFillOrder() (value int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_FillOrder]; !ok { + value = 1 + ok = true + return + } + if v := entry.GetInts(); len(v) == 1 { + value = v[0] + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetDocumentName() (value string, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_DocumentName]; !ok { + return + } + value = entry.GetString() + return +} + +func (p *tifTagGetter) GetImageDescription() (value string, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_ImageDescription]; !ok { + return + } + value = entry.GetString() + return +} + +func (p *tifTagGetter) GetMake() (value string, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_Make]; !ok { + return + } + value = entry.GetString() + return +} + +func (p *tifTagGetter) GetModel() (value string, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_Model]; !ok { + return + } + value = entry.GetString() + return +} + +func (p *tifTagGetter) GetStripOffsets() (value []int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_StripOffsets]; !ok { + return + } + value = entry.GetInts() + return +} + +func (p *tifTagGetter) GetOrientation() (value int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_Orientation]; !ok { + value = 1 + ok = true + return + } + if v := entry.GetInts(); len(v) == 1 { + value = v[0] + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetSamplesPerPixel() (value int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_SamplesPerPixel]; !ok { + value = 1 + ok = true + return + } + if v := entry.GetInts(); len(v) == 1 { + value = v[0] + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetRowsPerStrip() (value int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_RowsPerStrip]; !ok { + return + } + if v := entry.GetInts(); len(v) == 1 { + value = v[0] + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetStripByteCounts() (value []int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_StripByteCounts]; !ok { + return + } + value = entry.GetInts() + return +} + +func (p *tifTagGetter) GetMinSampleValue() (value []int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_MinSampleValue]; !ok { + value = []int64{0} + ok = true + return + } + value = entry.GetInts() + return +} + +func (p *tifTagGetter) GetMaxSampleValue() (value []int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_MaxSampleValue]; !ok { + return + } + value = entry.GetInts() + return +} + +func (p *tifTagGetter) GetXResolution() (value [2]int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_XResolution]; !ok { + return + } + if v := entry.GetInts(); len(v) == 2 { + value = [2]int64{v[0], v[1]} + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetYResolution() (value [2]int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_YResolution]; !ok { + return + } + if v := entry.GetInts(); len(v) == 2 { + value = [2]int64{v[0], v[1]} + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetPlanarConfiguration() (value int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_PlanarConfiguration]; !ok { + value = 1 + ok = true + return + } + if v := entry.GetInts(); len(v) == 1 { + value = v[0] + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetPageName() (value string, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_PageName]; !ok { + return + } + value = entry.GetString() + return +} + +func (p *tifTagGetter) GetXPosition() (value [2]int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_XPosition]; !ok { + return + } + if v := entry.GetInts(); len(v) == 2 { + value = [2]int64{v[0], v[1]} + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetYPosition() (value [2]int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_YPosition]; !ok { + return + } + if v := entry.GetInts(); len(v) == 2 { + value = [2]int64{v[0], v[1]} + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetFreeOffsets() (value []int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_FreeOffsets]; !ok { + return + } + value = entry.GetInts() + return +} + +func (p *tifTagGetter) GetFreeByteCounts() (value []int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_FreeByteCounts]; !ok { + return + } + value = entry.GetInts() + return +} + +func (p *tifTagGetter) GetGrayResponseUnit() (value int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_GrayResponseUnit]; !ok { + return + } + if v := entry.GetInts(); len(v) == 1 { + value = v[0] + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetGrayResponseCurve() (value []int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_GrayResponseCurve]; !ok { + return + } + value = entry.GetInts() + return +} + +func (p *tifTagGetter) GetT4Options() (value int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_T4Options]; !ok { + value = 0 + ok = true + return + } + if v := entry.GetInts(); len(v) == 1 { + value = v[0] + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetT6Options() (value int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_T6Options]; !ok { + value = 0 + ok = true + return + } + if v := entry.GetInts(); len(v) == 1 { + value = v[0] + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetResolutionUnit() (value TagValue_ResolutionUnitType, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_ResolutionUnit]; !ok { + value = TagValue_ResolutionUnitType_PerInch + ok = true + return + } + if v := entry.GetInts(); len(v) == 1 { + value = TagValue_ResolutionUnitType(v[0]) + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetPageNumber() (value []int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_PageNumber]; !ok { + return + } + value = entry.GetInts() + return +} + +func (p *tifTagGetter) GetTransferFunction() (value []int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_TransferFunction]; !ok { + return + } + value = entry.GetInts() + return +} + +func (p *tifTagGetter) GetSoftware() (value string, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_Software]; !ok { + return + } + value = entry.GetString() + return +} + +func (p *tifTagGetter) GetDateTime() (value time.Time, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_DateTime]; !ok { + return + } + var year, month, day, hour, min, sec int + if _, err := fmt.Sscanf(entry.GetString(), "%d:%d:%d %d:%d:%d", + &year, &month, &day, + &hour, &min, &sec, + ); err != nil { + ok = false + return + } + value = time.Date(year, time.Month(month), day, hour, min, sec, 0, nil) + return +} + +func (p *tifTagGetter) GetArtist() (value string, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_Artist]; !ok { + return + } + value = entry.GetString() + return +} + +func (p *tifTagGetter) GetHostComputer() (value string, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_HostComputer]; !ok { + return + } + value = entry.GetString() + return +} + +func (p *tifTagGetter) GetPredictor() (value TagValue_PredictorType, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_Predictor]; !ok { + value = TagValue_PredictorType_None + ok = true + return + } + if v := entry.GetInts(); len(v) == 1 { + value = TagValue_PredictorType(v[0]) + } + return +} + +func (p *tifTagGetter) GetWhitePoint() (value [][2]int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_WhitePoint]; !ok { + return + } + value = entry.GetRationals() + return +} + +func (p *tifTagGetter) GetPrimaryChromaticities() (value [][2]int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_PrimaryChromaticities]; !ok { + return + } + value = entry.GetRationals() + return +} + +func (p *tifTagGetter) GetColorMap() (value [][3]uint16, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_ColorMap]; !ok { + return + } + v := entry.GetInts() + if len(v) == 0 || len(v)%3 != 0 { + ok = false + return + } + numcolors := len(v) / 3 + value = make([][3]uint16, len(v)/3) + for i := 0; i < len(value); i++ { + value[i] = [3]uint16{ + uint16(v[i+0*numcolors]), + uint16(v[i+1*numcolors]), + uint16(v[i+2*numcolors]), + } + } + return +} + +func (p *tifTagGetter) GetHalftoneHints() (value []int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_HalftoneHints]; !ok { + return + } + value = entry.GetInts() + return +} + +func (p *tifTagGetter) GetTileWidth() (value int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_TileWidth]; !ok { + return + } + if v := entry.GetInts(); len(v) == 1 { + value = v[0] + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetTileLength() (value int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_TileLength]; !ok { + return + } + if v := entry.GetInts(); len(v) == 1 { + value = v[0] + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetTileOffsets() (value []int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_TileOffsets]; !ok { + return + } + value = entry.GetInts() + return +} + +func (p *tifTagGetter) GetTileByteCounts() (value []int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_TileByteCounts]; !ok { + return + } + value = entry.GetInts() + return +} + +func (p *tifTagGetter) GetSubIFD() (value []int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_SubIFD]; !ok { + return + } + value = entry.GetInts() + return +} + +func (p *tifTagGetter) GetInkSet() (value int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_InkSet]; !ok { + value = 1 + ok = true + return + } + if v := entry.GetInts(); len(v) == 1 { + value = v[0] + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetInkNames() (value string, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_InkNames]; !ok { + return + } + value = entry.GetString() + return +} + +func (p *tifTagGetter) GetNumberOfInks() (value int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_NumberOfInks]; !ok { + value = 4 + ok = true + return + } + if v := entry.GetInts(); len(v) == 1 { + value = v[0] + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetDotRange() (value []int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_DotRange]; !ok { + return + } + value = entry.GetInts() + return +} + +func (p *tifTagGetter) GetTargetPrinter() (value string, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_TargetPrinter]; !ok { + return + } + value = entry.GetString() + return +} + +func (p *tifTagGetter) GetExtraSamples() (value int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_ExtraSamples]; !ok { + return + } + if v := entry.GetInts(); len(v) == 1 { + value = v[0] + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetSampleFormat() (value []int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_SampleFormat]; !ok { + value = []int64{1} + ok = true + return + } + value = entry.GetInts() + return +} + +func (p *tifTagGetter) GetSMinSampleValue() (value []float64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_SMinSampleValue]; !ok { + return + } + value = entry.GetFloats() + return +} + +func (p *tifTagGetter) GetSMaxSampleValue() (value []float64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_SMaxSampleValue]; !ok { + return + } + value = entry.GetFloats() + return +} + +func (p *tifTagGetter) GetTransferRange() (value []int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_TransferRange]; !ok { + return + } + value = entry.GetInts() + return +} + +func (p *tifTagGetter) GetJPEGProc() (value int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_JPEGProc]; !ok { + return + } + if v := entry.GetInts(); len(v) == 1 { + value = v[0] + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetJPEGInterchangeFormat() (value int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_JPEGInterchangeFormat]; !ok { + return + } + if v := entry.GetInts(); len(v) == 1 { + value = v[0] + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetJPEGInterchangeFormatLength() (value int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_JPEGInterchangeFormatLength]; !ok { + return + } + if v := entry.GetInts(); len(v) == 1 { + value = v[0] + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetJPEGRestartInterval() (value int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_JPEGRestartInterval]; !ok { + return + } + if v := entry.GetInts(); len(v) == 1 { + value = v[0] + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetJPEGLosslessPredictors() (value []int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_JPEGLosslessPredictors]; !ok { + return + } + value = entry.GetInts() + return +} + +func (p *tifTagGetter) GetJPEGPointTransforms() (value []int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_JPEGPointTransforms]; !ok { + return + } + value = entry.GetInts() + return +} + +func (p *tifTagGetter) GetJPEGQTables() (value []int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_JPEGQTables]; !ok { + return + } + value = entry.GetInts() + return +} + +func (p *tifTagGetter) GetJPEGDCTables() (value []int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_JPEGDCTables]; !ok { + return + } + value = entry.GetInts() + return +} + +func (p *tifTagGetter) GetJPEGACTables() (value []int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_JPEGACTables]; !ok { + return + } + value = entry.GetInts() + return +} + +func (p *tifTagGetter) GetYCbCrCoefficients() (value [][2]int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_YCbCrCoefficients]; !ok { + return + } + value = entry.GetRationals() + return +} + +func (p *tifTagGetter) GetYCbCrSubSampling() (value []int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_YCbCrSubSampling]; !ok { + value = []int64{2, 2} + ok = true + return + } + value = entry.GetInts() + return +} + +func (p *tifTagGetter) GetYCbCrPositioning() (value int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_YCbCrPositioning]; !ok { + value = 1 + ok = true + return + } + if v := entry.GetInts(); len(v) == 1 { + value = v[0] + } else { + ok = false + } + return +} + +func (p *tifTagGetter) GetReferenceBlackWhite() (value []int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_ReferenceBlackWhite]; !ok { + return + } + value = entry.GetInts() + return +} + +func (p *tifTagGetter) GetCopyright() (value string, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_Copyright]; !ok { + return + } + value = entry.GetString() + return +} + +func (p *tifTagGetter) GetModelPixelScaleTag() (value []float64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_ModelPixelScaleTag]; !ok { + return + } + value = entry.GetFloats() + return +} + +func (p *tifTagGetter) GetIrasBTransformationMatrix() (value []float64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_IrasBTransformationMatrix]; !ok { + return + } + value = entry.GetFloats() + return +} + +func (p *tifTagGetter) GetModelTiepointTag() (value []float64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_ModelTiepointTag]; !ok { + return + } + value = entry.GetFloats() + return +} + +func (p *tifTagGetter) GetModelTransformationTag() (value []float64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_ModelTransformationTag]; !ok { + return + } + value = entry.GetFloats() + return +} + +func (p *tifTagGetter) GetExifIFD() (value []int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_ExifIFD]; !ok { + return + } + value = entry.GetInts() + return +} + +func (p *tifTagGetter) GetGeoKeyDirectoryTag() (value []int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_GeoKeyDirectoryTag]; !ok { + return + } + value = entry.GetInts() + return +} + +func (p *tifTagGetter) GetGeoDoubleParamsTag() (value []float64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_GeoDoubleParamsTag]; !ok { + return + } + value = entry.GetFloats() + return +} + +func (p *tifTagGetter) GetGeoAsciiParamsTag() (value string, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_GeoAsciiParamsTag]; !ok { + return + } + value = entry.GetString() + return +} + +func (p *tifTagGetter) GetGPSIFD() (value []int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_GPSIFD]; !ok { + return + } + value = entry.GetInts() + return +} + +func (p *tifTagGetter) GetInteroperabilityIFD() (value []int64, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[TagType_InteroperabilityIFD]; !ok { + return + } + value = entry.GetInts() + return +} + +func (p *tifTagGetter) GetUnknown(tag TagType) (value []byte, ok bool) { + var entry *IFDEntry + if entry, ok = p.EntryMap[tag]; !ok { + return + } + value = entry.Data + return +} + +func (p *tifTagGetter) private() { + return +} diff --git a/vendor/github.com/chai2010/tiff/tiff_ifd_tag_setter.go b/vendor/github.com/chai2010/tiff/tiff_ifd_tag_setter.go new file mode 100644 index 00000000..5fa723ec --- /dev/null +++ b/vendor/github.com/chai2010/tiff/tiff_ifd_tag_setter.go @@ -0,0 +1,12 @@ +// Copyright 2014 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tiff + +var _ TagSetter = (*tifTagSetter)(nil) + +type tifTagSetter struct { + EntryMap map[TagType]*IFDEntry + TagSetter +} diff --git a/vendor/github.com/chai2010/tiff/tiff_types.go b/vendor/github.com/chai2010/tiff/tiff_types.go new file mode 100644 index 00000000..9b821061 --- /dev/null +++ b/vendor/github.com/chai2010/tiff/tiff_types.go @@ -0,0 +1,408 @@ +// Copyright 2014 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tiff + +/* + * NB: In the comments below, + * - items marked with a + are obsoleted by revision 5.0, + * - items marked with a ! are introduced in revision 6.0. + * - items marked with a % are introduced post revision 6.0. + * - items marked with a $ are obsoleted by revision 6.0. + * - items marked with a & are introduced by Adobe DNG specification. + */ + +const ( + ClassicTiffLittleEnding = "II\x2A\x00" + ClassicTiffBigEnding = "MM\x00\x2A" + BigTiffLittleEnding = "II\x2B\x00" + BigTiffBigEnding = "MM\x00\x2B" +) + +type TiffType uint16 + +const ( + TiffType_ClassicTIFF TiffType = 42 + TiffType_BigTIFF TiffType = 43 +) + +type ImageType uint16 + +const ( + ImageType_Nil ImageType = iota + ImageType_Bilevel + ImageType_BilevelInvert + ImageType_Paletted + ImageType_Gray + ImageType_GrayInvert + ImageType_RGB + ImageType_RGBA + ImageType_NRGBA +) + +type DataType uint16 + +const ( + DataType_Nil DataType = 0 // placeholder, invalid + DataType_Byte DataType = 1 // 8-bit unsigned integer + DataType_ASCII DataType = 2 // 8-bit bytes w/ last byte null + DataType_Short DataType = 3 // 16-bit unsigned integer + DataType_Long DataType = 4 // 32-bit unsigned integer + DataType_Rational DataType = 5 // 64-bit unsigned fraction + DataType_SByte DataType = 6 // !8-bit signed integer + DataType_Undefined DataType = 7 // !8-bit untyped data + DataType_SShort DataType = 8 // !16-bit signed integer + DataType_SLong DataType = 9 // !32-bit signed integer + DataType_SRational DataType = 10 // !64-bit signed fraction + DataType_Float DataType = 11 // !32-bit IEEE floating point + DataType_Double DataType = 12 // !64-bit IEEE floating point + DataType_IFD DataType = 13 // %32-bit unsigned integer (offset) + DataType_Long8 DataType = 16 // BigTIFF 64-bit unsigned integer + DataType_SLong8 DataType = 17 // BigTIFF 64-bit signed integer + DataType_IFD8 DataType = 18 // BigTIFF 64-bit unsigned integer (offset) +) + +type ( + TagType uint16 + TagValue_NewSubfileType TagType + TagValue_SubfileType TagType + TagValue_CompressionType TagType + TagValue_PhotometricType TagType + TagValue_PredictorType TagType + TagValue_ResolutionUnitType TagType + TagValue_SampleFormatType TagType +) + +const ( + _ = 0 // Type(A/B/C/*), Num(1/*), Required, # comment + TagType_NewSubfileType TagType = 254 // LONG , 1, # Default=0. subfile data descriptor + _ = 0 // + TagValue_NewSubfileType_Nil TagValue_NewSubfileType = 0 // + TagValue_NewSubfileType_Reduced TagValue_NewSubfileType = 1 // # bit0, reduced resolution version + TagValue_NewSubfileType_Page TagValue_NewSubfileType = 2 // # bit1, one page of many + TagValue_NewSubfileType_Reduced_Page TagValue_NewSubfileType = 3 // + TagValue_NewSubfileType_Mask TagValue_NewSubfileType = 4 // # bit2, transparency mask + TagValue_NewSubfileType_Reduced_Mask TagValue_NewSubfileType = 5 // + TagValue_NewSubfileType_Page_Mask TagValue_NewSubfileType = 6 // + TagValue_NewSubfileType_Reduced_Page_Mask TagValue_NewSubfileType = 7 // + _ = 0 // + TagType_SubfileType TagType = 255 // SHORT, 1, # kind of data in subfile + _ = 0 // + TagValue_SubfileType_Image TagValue_SubfileType = 1 // # full resolution image data + TagValue_SubfileType_ReducedImage TagValue_SubfileType = 2 // # reduced size image data + TagValue_SubfileType_Page TagValue_SubfileType = 3 // # one page of many + _ = 0 // + TagType_ImageWidth TagType = 256 // SHORT/LONG/LONG8, 1, # Required + TagType_ImageLength TagType = 257 // SHORT/LONG/LONG8, 1, # Required + TagType_BitsPerSample TagType = 258 // SHORT, *, # Default=1. See SamplesPerPixel + TagType_Compression TagType = 259 // SHORT, 1, # Default=1 + _ = 0 // + TagValue_CompressionType_Nil TagValue_CompressionType = 0 // + TagValue_CompressionType_None TagValue_CompressionType = 1 // + TagValue_CompressionType_CCITT TagValue_CompressionType = 2 // + TagValue_CompressionType_G3 TagValue_CompressionType = 3 // # Group 3 Fax. + TagValue_CompressionType_G4 TagValue_CompressionType = 4 // # Group 4 Fax. + TagValue_CompressionType_LZW TagValue_CompressionType = 5 // + TagValue_CompressionType_JPEGOld TagValue_CompressionType = 6 // # Superseded by cJPEG. + TagValue_CompressionType_JPEG TagValue_CompressionType = 7 // + TagValue_CompressionType_Deflate TagValue_CompressionType = 8 // # zlib compression. + TagValue_CompressionType_PackBits TagValue_CompressionType = 32773 // + TagValue_CompressionType_DeflateOld TagValue_CompressionType = 32946 // # Superseded by cDeflate. + _ = 0 // + TagType_PhotometricInterpretation TagType = 262 // SHORT, 1, + _ = 0 // + TagValue_PhotometricType_WhiteIsZero TagValue_PhotometricType = 0 // + TagValue_PhotometricType_BlackIsZero TagValue_PhotometricType = 1 // + TagValue_PhotometricType_RGB TagValue_PhotometricType = 2 // + TagValue_PhotometricType_Paletted TagValue_PhotometricType = 3 // + TagValue_PhotometricType_TransMask TagValue_PhotometricType = 4 // # transparency mask + TagValue_PhotometricType_CMYK TagValue_PhotometricType = 5 // + TagValue_PhotometricType_YCbCr TagValue_PhotometricType = 6 // + TagValue_PhotometricType_CIELab TagValue_PhotometricType = 8 // + _ = 0 // + TagType_Threshholding TagType = 263 // SHORT, 1, # Default=1 + TagType_CellWidth TagType = 264 // SHORT, 1, + TagType_CellLenght TagType = 265 // SHORT, 1, + TagType_FillOrder TagType = 266 // SHORT, 1, # Default=1 + TagType_DocumentName TagType = 269 // ASCII + TagType_ImageDescription TagType = 270 // ASCII + TagType_Make TagType = 271 // ASCII + TagType_Model TagType = 272 // ASCII + TagType_StripOffsets TagType = 273 // SHORT/LONG/LONG8, *, # StripsPerImage + TagType_Orientation TagType = 274 // SHORT, 1, # Default=1 + TagType_SamplesPerPixel TagType = 277 // SHORT, 1, # Default=1 + TagType_RowsPerStrip TagType = 278 // SHORT/LONG/LONG8, 1, + TagType_StripByteCounts TagType = 279 // SHORT/LONG/LONG8, *, # StripsPerImage + TagType_MinSampleValue TagType = 280 // SHORT, *, # Default=0 + TagType_MaxSampleValue TagType = 281 // SHORT, *, # Default=2^BitsPerSample-1 + TagType_XResolution TagType = 282 // RATIONAL, 1, # Required? + TagType_YResolution TagType = 283 // RATIONAL, 1, # Required? + TagType_PlanarConfiguration TagType = 284 // SHORT, 1, # Defaule=1 + TagType_PageName TagType = 285 // ASCII + TagType_XPosition TagType = 286 // RATIONAL, 1 + TagType_YPosition TagType = 287 // RATIONAL, 1 + TagType_FreeOffsets TagType = 288 // LONG/LONG8, * + TagType_FreeByteCounts TagType = 289 // LONG/LONG8, * + TagType_GrayResponseUnit TagType = 290 // SHORT, 1, + TagType_GrayResponseCurve TagType = 291 // SHORT, *, # 2**BitPerSample + TagType_T4Options TagType = 292 // LONG, 1, # Default=0 + TagType_T6Options TagType = 293 // LONG, 1, # Default=0 + TagType_ResolutionUnit TagType = 296 // SHORT, 1, # Default=2 + _ = 0 // + TagValue_ResolutionUnitType_None TagValue_ResolutionUnitType = 1 // + TagValue_ResolutionUnitType_PerInch TagValue_ResolutionUnitType = 2 // # Dots per inch. + TagValue_ResolutionUnitType_PerCM TagValue_ResolutionUnitType = 3 // # Dots per centimeter. + _ = 0 // + TagType_PageNumber TagType = 297 // SHORT, 2, + TagType_TransferFunction TagType = 301 // SHORT, *, # {1 or SamplesPerPixel}*2**BitPerSample + TagType_Software TagType = 305 // ASCII + TagType_DateTime TagType = 306 // ASCII, 20, # YYYY:MM:DD HH:MM:SS, include NULL + TagType_Artist TagType = 315 // ASCII + TagType_HostComputer TagType = 316 // ASCII + TagType_Predictor TagType = 317 // SHORT, 1, # Default=1 + _ = 0 // + TagValue_PredictorType_None TagValue_PredictorType = 1 // + TagValue_PredictorType_Horizontal TagValue_PredictorType = 2 // + _ = 0 // + TagType_WhitePoint TagType = 318 // RATIONAL, 2 + TagType_PrimaryChromaticities TagType = 319 // RATIONAL, 6 + TagType_ColorMap TagType = 320 // SHORT, *, # 3*(2**BitPerSample) + TagType_HalftoneHints TagType = 321 // SHORT, 2 + TagType_TileWidth TagType = 322 // SHORT/LONG, 1 + TagType_TileLength TagType = 323 // SHORT/LONG, 1 + TagType_TileOffsets TagType = 324 // LONG/LONG8, *, # TilesPerImage + TagType_TileByteCounts TagType = 325 // SHORT/LONG, *, # TilesPerImage + TagType_BadFaxLines TagType = 326 // ingore # Used in the TIFF-F standard, denotes the number of 'bad' scan lines encountered by the facsimile device. + TagType_CleanFaxData TagType = 327 // ingore # Used in the TIFF-F standard, indicates if 'bad' lines encountered during reception are stored in the data, or if 'bad' lines have been replaced by the receiver. + TagType_ConsecutiveBadFaxLines TagType = 328 // ingore # Used in the TIFF-F standard, denotes the maximum number of consecutive 'bad' scanlines received. + TagType_SubIFD TagType = 330 // IFD, * # IFD pointer + TagType_InkSet TagType = 332 // SHORT, 1, # Default=1 + TagType_InkNames TagType = 333 // ASCII + TagType_NumberOfInks TagType = 334 // SHORT, 1, # Default=4 + TagType_DotRange TagType = 336 // BYTE/SHORT, # Default=[0,2^BitsPerSample-1] + TagType_TargetPrinter TagType = 337 // ASCII + TagType_ExtraSamples TagType = 338 // BYTE, 1, + TagType_SampleFormat TagType = 339 // SHORT, *, # SamplesPerPixel. Default=1 + _ = 0 // + TagValue_SampleFormatType_Uint TagValue_SampleFormatType = 1 // + TagValue_SampleFormatType_TwoInt TagValue_SampleFormatType = 2 // + TagValue_SampleFormatType_Float TagValue_SampleFormatType = 3 // + TagValue_SampleFormatType_Undefined TagValue_SampleFormatType = 4 // + _ = 0 // + TagType_SMinSampleValue TagType = 340 // *, *, # SamplesPerPixel, try double + TagType_SMaxSampleValue TagType = 341 // *, *, # SamplesPerPixel, try double + TagType_TransferRange TagType = 342 // SHORT, 6, + TagType_ClipPath TagType = 343 // ingore # Mirrors the essentials of PostScript's path creation functionality. + TagType_XClipPathUnits TagType = 344 // ingore # The number of units that span the width of the image, in terms of integer ClipPath coordinates. + TagType_YClipPathUnits TagType = 345 // ingore # The number of units that span the height of the image, in terms of integer ClipPath coordinates. + TagType_Indexed TagType = 346 // ingore # Aims to broaden the support for indexed images to include support for any color space. + TagType_JPEGTables TagType = 347 // ingore # JPEG quantization and/or Huffman tables. + TagType_OPIProxy TagType = 351 // ingore # OPI-related. + TagType_GlobalParametersIFD TagType = 400 // ingore # Used in the TIFF-FX standard to point to an IFD containing tags that are globally applicable to the complete TIFF file. + TagType_ProfileType TagType = 401 // ingore # Used in the TIFF-FX standard, denotes the type of data stored in this file or IFD. + TagType_FaxProfile TagType = 402 // ingore # Used in the TIFF-FX standard, denotes the 'profile' that applies to this file. + TagType_CodingMethods TagType = 403 // ingore # Used in the TIFF-FX standard, indicates which coding methods are used in the file. + TagType_VersionYear TagType = 404 // ingore # Used in the TIFF-FX standard, denotes the year of the standard specified by the FaxProfile field. + TagType_ModeNumber TagType = 405 // ingore # Used in the TIFF-FX standard, denotes the mode of the standard specified by the FaxProfile field. + TagType_Decode TagType = 433 // ingore # Used in the TIFF-F and TIFF-FX standards, holds information about the ITULAB (PhotometricInterpretation = 10) encoding. + TagType_DefaultImageColor TagType = 434 // ingore # Defined in the Mixed Raster Content part of RFC 2301, is the default color needed in areas where no image is available. + TagType_JPEGProc TagType = 512 // SHORT, 1, + TagType_JPEGInterchangeFormat TagType = 513 // LONG, 1, + TagType_JPEGInterchangeFormatLength TagType = 514 // LONG, 1, + TagType_JPEGRestartInterval TagType = 515 // SHORT, 1, + TagType_JPEGLosslessPredictors TagType = 517 // SHORT, *, # SamplesPerPixel + TagType_JPEGPointTransforms TagType = 518 // SHORT, *, # SamplesPerPixel + TagType_JPEGQTables TagType = 519 // LONG, *, # SamplesPerPixel + TagType_JPEGDCTables TagType = 520 // LONG, *, # SamplesPerPixel + TagType_JPEGACTables TagType = 521 // LONG, *, # SamplesPerPixel + TagType_YCbCrCoefficients TagType = 529 // RATIONAL, 3 + TagType_YCbCrSubSampling TagType = 530 // SHORT, 2, # Default=[2,2] + TagType_YCbCrPositioning TagType = 531 // SHORT, 1, # Default=1 + TagType_ReferenceBlackWhite TagType = 532 // LONG , *, # 2*SamplesPerPixel + TagType_StripRowCounts TagType = 559 // ingore # Defined in the Mixed Raster Content part of RFC 2301, used to replace RowsPerStrip for IFDs with variable-sized strips. + TagType_XMP TagType = 700 // ingore # XML packet containing XMP metadata + TagType_ImageID TagType = 32781 // ingore # OPI-related. + TagType_ImageLayer TagType = 34732 // ingore # Defined in the Mixed Raster Content part of RFC 2301, used to denote the particular function of this Image in the mixed raster scheme. + TagType_Copyright TagType = 33432 // ASCII + TagType_WangAnnotation TagType = 32932 // ingore # Annotation data, as used in 'Imaging for Windows'. + TagType_MDFileTag TagType = 33445 // ingore # Specifies the pixel data format encoding in the Molecular Dynamics GEL file format. + TagType_MDScalePixel TagType = 33446 // ingore # Specifies a scale factor in the Molecular Dynamics GEL file format. + TagType_MDColorTable TagType = 33447 // ingore # Used to specify the conversion from 16bit to 8bit in the Molecular Dynamics GEL file format. + TagType_MDLabName TagType = 33448 // ingore # Name of the lab that scanned this file, as used in the Molecular Dynamics GEL file format. + TagType_MDSampleInfo TagType = 33449 // ingore # Information about the sample, as used in the Molecular Dynamics GEL file format. + TagType_MDPrepDate TagType = 33450 // ingore # Date the sample was prepared, as used in the Molecular Dynamics GEL file format. + TagType_MDPrepTime TagType = 33451 // ingore # Time the sample was prepared, as used in the Molecular Dynamics GEL file format. + TagType_MDFileUnits TagType = 33452 // ingore # Units for data in this file, as used in the Molecular Dynamics GEL file format. + TagType_ModelPixelScaleTag TagType = 33550 // DOUBLE # Used in interchangeable GeoTIFF files. + TagType_IPTC TagType = 33723 // ingore # IPTC (International Press Telecommunications Council) metadata. + TagType_INGRPacketDataTag TagType = 33918 // ingore # Intergraph Application specific storage. + TagType_INGRFlagRegisters TagType = 33919 // ingore # Intergraph Application specific flags. + TagType_IrasBTransformationMatrix TagType = 33920 // DOUBLE, 17 # Originally part of Intergraph's GeoTIFF tags, but likely understood by IrasB only. + TagType_ModelTiepointTag TagType = 33922 // DOUBLE # Originally part of Intergraph's GeoTIFF tags, but now used in interchangeable GeoTIFF files. + TagType_ModelTransformationTag TagType = 34264 // DOUBLE, 16 # Used in interchangeable GeoTIFF files. + TagType_Photoshop TagType = 34377 // ingore # Collection of Photoshop 'Image Resource Blocks'. + TagType_ExifIFD TagType = 34665 // IFD # A pointer to the Exif IFD. + TagType_ICCProfile TagType = 34675 // ingore # ICC profile data. + TagType_GeoKeyDirectoryTag TagType = 34735 // SHORT, *, # >= 4 + TagType_GeoDoubleParamsTag TagType = 34736 // DOUBLE + TagType_GeoAsciiParamsTag TagType = 34737 // ASCII + TagType_GPSIFD TagType = 34853 // IFD # A pointer to the Exif-related GPS Info IFD. + TagType_HylaFAXFaxRecvParams TagType = 34908 // ingore # Used by HylaFAX. + TagType_HylaFAXFaxSubAddress TagType = 34909 // ingore # Used by HylaFAX. + TagType_HylaFAXFaxRecvTime TagType = 34910 // ingore # Used by HylaFAX. + TagType_ImageSourceData TagType = 37724 // ingore # Used by Adobe Photoshop. + TagType_InteroperabilityIFD TagType = 40965 // IFD # A pointer to the Exif-related Interoperability IFD. + TagType_GDAL_METADATA TagType = 42112 // ingore # Used by the GDAL library, holds an XML list of name=value 'metadata' values about the image as a whole, and about specific samples. + TagType_GDAL_NODATA TagType = 42113 // ingore # Used by the GDAL library, contains an ASCII encoded nodata or background pixel value. + TagType_OceScanjobDescription TagType = 50215 // ingore # Used in the Oce scanning process. + TagType_OceApplicationSelector TagType = 50216 // ingore # Used in the Oce scanning process. + TagType_OceIdentificationNumber TagType = 50217 // ingore # Used in the Oce scanning process. + TagType_OceImageLogicCharacteristics TagType = 50218 // ingore # Used in the Oce scanning process. + TagType_DNGVersion TagType = 50706 // ingore # Used in IFD 0 of DNG files. + TagType_DNGBackwardVersion TagType = 50707 // ingore # Used in IFD 0 of DNG files. + TagType_UniqueCameraModel TagType = 50708 // ingore # Used in IFD 0 of DNG files. + TagType_LocalizedCameraModel TagType = 50709 // ingore # Used in IFD 0 of DNG files. + TagType_CFAPlaneColor TagType = 50710 // ingore # Used in Raw IFD of DNG files. + TagType_CFALayout TagType = 50711 // ingore # Used in Raw IFD of DNG files. + TagType_LinearizationTable TagType = 50712 // ingore # Used in Raw IFD of DNG files. + TagType_BlackLevelRepeatDim TagType = 50713 // ingore # Used in Raw IFD of DNG files. + TagType_BlackLevel TagType = 50714 // ingore # Used in Raw IFD of DNG files. + TagType_BlackLevelDeltaH TagType = 50715 // ingore # Used in Raw IFD of DNG files. + TagType_BlackLevelDeltaV TagType = 50716 // ingore # Used in Raw IFD of DNG files. + TagType_WhiteLevel TagType = 50717 // ingore # Used in Raw IFD of DNG files. + TagType_DefaultScale TagType = 50718 // ingore # Used in Raw IFD of DNG files. + TagType_DefaultCropOrigin TagType = 50719 // ingore # Used in Raw IFD of DNG files. + TagType_DefaultCropSize TagType = 50720 // ingore # Used in Raw IFD of DNG files. + TagType_ColorMatrix1 TagType = 50721 // ingore # Used in IFD 0 of DNG files. + TagType_ColorMatrix2 TagType = 50722 // ingore # Used in IFD 0 of DNG files. + TagType_CameraCalibration1 TagType = 50723 // ingore # Used in IFD 0 of DNG files. + TagType_CameraCalibration2 TagType = 50724 // ingore # Used in IFD 0 of DNG files. + TagType_ReductionMatrix1 TagType = 50725 // ingore # Used in IFD 0 of DNG files. + TagType_ReductionMatrix2 TagType = 50726 // ingore # Used in IFD 0 of DNG files. + TagType_AnalogBalance TagType = 50727 // ingore # Used in IFD 0 of DNG files. + TagType_AsShotNeutral TagType = 50728 // ingore # Used in IFD 0 of DNG files. + TagType_AsShotWhiteXY TagType = 50729 // ingore # Used in IFD 0 of DNG files. + TagType_BaselineExposure TagType = 50730 // ingore # Used in IFD 0 of DNG files. + TagType_BaselineNoise TagType = 50731 // ingore # Used in IFD 0 of DNG files. + TagType_BaselineSharpness TagType = 50732 // ingore # Used in IFD 0 of DNG files. + TagType_BayerGreenSplit TagType = 50733 // ingore # Used in Raw IFD of DNG files. + TagType_LinearResponseLimit TagType = 50734 // ingore # Used in IFD 0 of DNG files. + TagType_CameraSerialNumber TagType = 50735 // ingore # Used in IFD 0 of DNG files. + TagType_LensInfo TagType = 50736 // ingore # Used in IFD 0 of DNG files. + TagType_ChromaBlurRadius TagType = 50737 // ingore # Used in Raw IFD of DNG files. + TagType_AntiAliasStrength TagType = 50738 // ingore # Used in Raw IFD of DNG files. + TagType_DNGPrivateData TagType = 50740 // ingore # Used in IFD 0 of DNG files. + TagType_MakerNoteSafety TagType = 50741 // ingore # Used in IFD 0 of DNG files. + TagType_CalibrationIlluminant1 TagType = 50778 // ingore # Used in IFD 0 of DNG files. + TagType_CalibrationIlluminant2 TagType = 50779 // ingore # Used in IFD 0 of DNG files. + TagType_BestQualityScale TagType = 50780 // ingore # Used in Raw IFD of DNG files. + TagType_AliasLayerMetadata TagType = 50784 // ingore # Alias Sketchbook Pro layer usage description. + _ = 0 // +) + +// EXIF Tags +type ExifIFD_TagType TagType + +const ( + ExifIFD_TagType_ExposureTime ExifIFD_TagType = 33434 // ingore # Exposure time, given in seconds. + ExifIFD_TagType_FNumber ExifIFD_TagType = 33437 // ingore # The F number. + ExifIFD_TagType_ExposureProgram ExifIFD_TagType = 34850 // ingore # The class of the program used by the camera to set exposure when the picture is taken. + ExifIFD_TagType_SpectralSensitivity ExifIFD_TagType = 34852 // ingore # Indicates the spectral sensitivity of each channel of the camera used. + ExifIFD_TagType_ISOSpeedRatings ExifIFD_TagType = 34855 // ingore # Indicates the ISO Speed and ISO Latitude of the camera or input device as specified in ISO 12232. + ExifIFD_TagType_OECF ExifIFD_TagType = 34856 // ingore # Indicates the Opto-Electric Conversion Function (OECF) specified in ISO 14524. + ExifIFD_TagType_ExifVersion ExifIFD_TagType = 36864 // ingore # The version of the supported Exif standard. + ExifIFD_TagType_DateTimeOriginal ExifIFD_TagType = 36867 // ingore # The date and time when the original image data was generated. + ExifIFD_TagType_DateTimeDigitized ExifIFD_TagType = 36868 // ingore # The date and time when the image was stored as digital data. + ExifIFD_TagType_ComponentsConfiguration ExifIFD_TagType = 37121 // ingore # Specific to compressed data; specifies the channels and complements PhotometricInterpretation + ExifIFD_TagType_CompressedBitsPerPixel ExifIFD_TagType = 37122 // ingore # Specific to compressed data; states the compressed bits per pixel. + ExifIFD_TagType_ShutterSpeedValue ExifIFD_TagType = 37377 // ingore # Shutter speed. + ExifIFD_TagType_ApertureValue ExifIFD_TagType = 37378 // ingore # The lens aperture. + ExifIFD_TagType_BrightnessValue ExifIFD_TagType = 37379 // ingore # The value of brightness. + ExifIFD_TagType_ExposureBiasValue ExifIFD_TagType = 37380 // ingore # The exposure bias. + ExifIFD_TagType_MaxApertureValue ExifIFD_TagType = 37381 // ingore # The smallest F number of the lens. + ExifIFD_TagType_SubjectDistance ExifIFD_TagType = 37382 // ingore # The distance to the subject, given in meters. + ExifIFD_TagType_MeteringMode ExifIFD_TagType = 37383 // ingore # The metering mode. + ExifIFD_TagType_LightSource ExifIFD_TagType = 37384 // ingore # The kind of light source. + ExifIFD_TagType_Flash ExifIFD_TagType = 37385 // ingore # Indicates the status of flash when the image was shot. + ExifIFD_TagType_FocalLength ExifIFD_TagType = 37386 // ingore # The actual focal length of the lens, in mm. + ExifIFD_TagType_SubjectArea ExifIFD_TagType = 37396 // ingore # Indicates the location and area of the main subject in the overall scene. + ExifIFD_TagType_MakerNote ExifIFD_TagType = 37500 // ingore # Manufacturer specific information. + ExifIFD_TagType_UserComment ExifIFD_TagType = 37510 // ingore # Keywords or comments on the image; complements ImageDescription. + ExifIFD_TagType_SubsecTime ExifIFD_TagType = 37520 // ingore # A tag used to record fractions of seconds for the DateTime tag. + ExifIFD_TagType_SubsecTimeOriginal ExifIFD_TagType = 37521 // ingore # A tag used to record fractions of seconds for the DateTimeOriginal tag. + ExifIFD_TagType_SubsecTimeDigitized ExifIFD_TagType = 37522 // ingore # A tag used to record fractions of seconds for the DateTimeDigitized tag. + ExifIFD_TagType_FlashpixVersion ExifIFD_TagType = 40960 // ingore # The Flashpix format version supported by a FPXR file. + ExifIFD_TagType_ColorSpace ExifIFD_TagType = 40961 // ingore # The color space information tag is always recorded as the color space specifier. + ExifIFD_TagType_PixelXDimension ExifIFD_TagType = 40962 // ingore # Specific to compressed data; the valid width of the meaningful image. + ExifIFD_TagType_PixelYDimension ExifIFD_TagType = 40963 // ingore # Specific to compressed data; the valid height of the meaningful image. + ExifIFD_TagType_RelatedSoundFile ExifIFD_TagType = 40964 // ingore # Used to record the name of an audio file related to the image data. + ExifIFD_TagType_FlashEnergy ExifIFD_TagType = 41483 // ingore # Indicates the strobe energy at the time the image is captured, as measured in Beam Candle Power Seconds + ExifIFD_TagType_SpatialFrequencyResponse ExifIFD_TagType = 41484 // ingore # Records the camera or input device spatial frequency table and SFR values in the direction of image width, image height, and diagonal direction, as specified in ISO 12233. + ExifIFD_TagType_FocalPlaneXResolution ExifIFD_TagType = 41486 // ingore # Indicates the number of pixels in the image width (X) direction per FocalPlaneResolutionUnit on the camera focal plane. + ExifIFD_TagType_FocalPlaneYResolution ExifIFD_TagType = 41487 // ingore # Indicates the number of pixels in the image height (Y) direction per FocalPlaneResolutionUnit on the camera focal plane. + ExifIFD_TagType_FocalPlaneResolutionUnit ExifIFD_TagType = 41488 // ingore # Indicates the unit for measuring FocalPlaneXResolution and FocalPlaneYResolution. + ExifIFD_TagType_SubjectLocation ExifIFD_TagType = 41492 // ingore # Indicates the location of the main subject in the scene. + ExifIFD_TagType_ExposureIndex ExifIFD_TagType = 41493 // ingore # Indicates the exposure index selected on the camera or input device at the time the image is captured. + ExifIFD_TagType_SensingMethod ExifIFD_TagType = 41495 // ingore # Indicates the image sensor type on the camera or input device. + ExifIFD_TagType_FileSource ExifIFD_TagType = 41728 // ingore # Indicates the image source. + ExifIFD_TagType_SceneType ExifIFD_TagType = 41729 // ingore # Indicates the type of scene. + ExifIFD_TagType_CFAPattern ExifIFD_TagType = 41730 // ingore # Indicates the color filter array (CFA) geometric pattern of the image sensor when a one-chip color area sensor is used. + ExifIFD_TagType_CustomRendered ExifIFD_TagType = 41985 // ingore # Indicates the use of special processing on image data, such as rendering geared to output. + ExifIFD_TagType_ExposureMode ExifIFD_TagType = 41986 // ingore # Indicates the exposure mode set when the image was shot. + ExifIFD_TagType_WhiteBalance ExifIFD_TagType = 41987 // ingore # Indicates the white balance mode set when the image was shot. + ExifIFD_TagType_DigitalZoomRatio ExifIFD_TagType = 41988 // ingore # Indicates the digital zoom ratio when the image was shot. + ExifIFD_TagType_FocalLengthIn35mmFilm ExifIFD_TagType = 41989 // ingore # Indicates the equivalent focal length assuming a 35mm film camera, in mm. + ExifIFD_TagType_SceneCaptureType ExifIFD_TagType = 41990 // ingore # Indicates the type of scene that was shot. + ExifIFD_TagType_GainControl ExifIFD_TagType = 41991 // ingore # Indicates the degree of overall image gain adjustment. + ExifIFD_TagType_Contrast ExifIFD_TagType = 41992 // ingore # Indicates the direction of contrast processing applied by the camera when the image was shot. + ExifIFD_TagType_Saturation ExifIFD_TagType = 41993 // ingore # Indicates the direction of saturation processing applied by the camera when the image was shot. + ExifIFD_TagType_Sharpness ExifIFD_TagType = 41994 // ingore # Indicates the direction of sharpness processing applied by the camera when the image was shot. + ExifIFD_TagType_DeviceSettingDescription ExifIFD_TagType = 41995 // ingore # This tag indicates information on the picture-taking conditions of a particular camera model. + ExifIFD_TagType_SubjectDistanceRange ExifIFD_TagType = 41996 // ingore # Indicates the distance to the subject. + ExifIFD_TagType_ImageUniqueID ExifIFD_TagType = 42016 // ingore # Indicates an identifier assigned uniquely to each image. +) + +// GPS Tags +type GPSIFD_TagType TagType + +const ( + GPSIFD_TagType_GPSVersionID GPSIFD_TagType = 0 // ingore # Indicates the version of GPSInfoIFD. + GPSIFD_TagType_GPSLatitudeRef GPSIFD_TagType = 1 // ingore # Indicates whether the latitude is north or south latitude. + GPSIFD_TagType_GPSLatitude GPSIFD_TagType = 2 // ingore # Indicates the latitude. + GPSIFD_TagType_GPSLongitudeRef GPSIFD_TagType = 3 // ingore # Indicates whether the longitude is east or west longitude. + GPSIFD_TagType_GPSLongitude GPSIFD_TagType = 4 // ingore # Indicates the longitude. + GPSIFD_TagType_GPSAltitudeRef GPSIFD_TagType = 5 // ingore # Indicates the altitude used as the reference altitude. + GPSIFD_TagType_GPSAltitude GPSIFD_TagType = 6 // ingore # Indicates the altitude based on the reference in GPSAltitudeRef. + GPSIFD_TagType_GPSTimeStamp GPSIFD_TagType = 7 // ingore # Indicates the time as UTC (Coordinated Universal Time). + GPSIFD_TagType_GPSSatellites GPSIFD_TagType = 8 // ingore # Indicates the GPS satellites used for measurements. + GPSIFD_TagType_GPSStatus GPSIFD_TagType = 9 // ingore # Indicates the status of the GPS receiver when the image is recorded. + GPSIFD_TagType_GPSMeasureMode GPSIFD_TagType = 10 // ingore # Indicates the GPS measurement mode. + GPSIFD_TagType_GPSDOP GPSIFD_TagType = 11 // ingore # Indicates the GPS DOP (data degree of precision). + GPSIFD_TagType_GPSSpeedRef GPSIFD_TagType = 12 // ingore # Indicates the unit used to express the GPS receiver speed of movement. + GPSIFD_TagType_GPSSpeed GPSIFD_TagType = 13 // ingore # Indicates the speed of GPS receiver movement. + GPSIFD_TagType_GPSTrackRef GPSIFD_TagType = 14 // ingore # Indicates the reference for giving the direction of GPS receiver movement. + GPSIFD_TagType_GPSTrack GPSIFD_TagType = 15 // ingore # Indicates the direction of GPS receiver movement. + GPSIFD_TagType_GPSImgDirectionRef GPSIFD_TagType = 16 // ingore # Indicates the reference for giving the direction of the image when it is captured. + GPSIFD_TagType_GPSImgDirection GPSIFD_TagType = 17 // ingore # Indicates the direction of the image when it was captured. + GPSIFD_TagType_GPSMapDatum GPSIFD_TagType = 18 // ingore # Indicates the geodetic survey data used by the GPS receiver. + GPSIFD_TagType_GPSDestLatitudeRef GPSIFD_TagType = 19 // ingore # Indicates whether the latitude of the destination point is north or south latitude. + GPSIFD_TagType_GPSDestLatitude GPSIFD_TagType = 20 // ingore # Indicates the latitude of the destination point. + GPSIFD_TagType_GPSDestLongitudeRef GPSIFD_TagType = 21 // ingore # Indicates whether the longitude of the destination point is east or west longitude. + GPSIFD_TagType_GPSDestLongitude GPSIFD_TagType = 22 // ingore # Indicates the longitude of the destination point. + GPSIFD_TagType_GPSDestBearingRef GPSIFD_TagType = 23 // ingore # Indicates the reference used for giving the bearing to the destination point. + GPSIFD_TagType_GPSDestBearing GPSIFD_TagType = 24 // ingore # Indicates the bearing to the destination point. + GPSIFD_TagType_GPSDestDistanceRef GPSIFD_TagType = 25 // ingore # Indicates the unit used to express the distance to the destination point. + GPSIFD_TagType_GPSDestDistance GPSIFD_TagType = 26 // ingore # Indicates the distance to the destination point. + GPSIFD_TagType_GPSProcessingMethod GPSIFD_TagType = 27 // ingore # A character string recording the name of the method used for location finding. + GPSIFD_TagType_GPSAreaInformation GPSIFD_TagType = 28 // ingore # A character string recording the name of the GPS area. + GPSIFD_TagType_GPSDateStamp GPSIFD_TagType = 29 // ingore # A character string recording date and time information relative to UTC (Coordinated Universal Time). + GPSIFD_TagType_GPSDifferential GPSIFD_TagType = 30 // ingore # Indicates whether differential correction is applied to the GPS receiver. +) + +// Interoperability Tags +type InteroperabilityIFD_TagType TagType + +const ( + InteroperabilityIFD_TagType_InteroperabilityIndex InteroperabilityIFD_TagType = 1 // ingore # Indicates the identification of the Interoperability rule. +) diff --git a/vendor/github.com/chai2010/tiff/tiff_types_helper.go b/vendor/github.com/chai2010/tiff/tiff_types_helper.go new file mode 100644 index 00000000..aab0682b --- /dev/null +++ b/vendor/github.com/chai2010/tiff/tiff_types_helper.go @@ -0,0 +1,108 @@ +// Copyright 2015 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tiff + +func (p TiffType) Valid() bool { + return p == TiffType_ClassicTIFF || p == TiffType_BigTIFF +} + +func (d DataType) Valid() bool { + if d <= DataType_Nil || d > DataType_IFD8 { + return false + } + _, ok := _DataTypeTable[d] + return ok +} + +func (d DataType) IsIntType() bool { + switch d { + case DataType_Byte, DataType_Short, DataType_Long: + return true + case DataType_SByte, DataType_SShort, DataType_SLong: + return true + case DataType_IFD, DataType_IFD8: + return true + } + return false +} +func (d DataType) IsFloatType() bool { + switch d { + case DataType_Float, DataType_Double: + return true + } + return false +} +func (d DataType) IsRationalType() bool { + switch d { + case DataType_Rational, DataType_SRational: + return true + } + return false +} +func (d DataType) IsStringType() bool { + switch d { + case DataType_ASCII: + return true + } + return false +} + +func (d DataType) ByteSize() int { + switch d { + case DataType_Byte: + return 1 + case DataType_ASCII: + return 1 + case DataType_Short: + return 2 + case DataType_Long: + return 4 + case DataType_Rational: + return 8 + case DataType_SByte: + return 1 + case DataType_Undefined: + return 1 + case DataType_SShort: + return 2 + case DataType_SLong: + return 4 + case DataType_SRational: + return 8 + case DataType_Float: + return 4 + case DataType_Double: + return 8 + case DataType_IFD: + return 4 // LONG + case DataType_Long8: + return 8 + case DataType_SLong8: + return 8 + case DataType_IFD8: + return 8 // LONG8 + } + return 0 +} + +func (d TagType) _AcceptDataType(dataType DataType) bool { + if !dataType.Valid() { + return false + } + dataTypeList, _ := _TagType_TypesTable[d] + if len(dataTypeList) == 0 { + return true + } + for _, v := range dataTypeList { + if v == dataType { + return true + } + } + return false +} + +func (d TagType) Valid() bool { + return d != 0 +} diff --git a/vendor/github.com/chai2010/tiff/utils.go b/vendor/github.com/chai2010/tiff/utils.go new file mode 100644 index 00000000..c3618cb6 --- /dev/null +++ b/vendor/github.com/chai2010/tiff/utils.go @@ -0,0 +1,36 @@ +// Copyright 2015 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tiff + +import ( + "image" + "os" +) + +func Load(filename string) (m image.Image, err error) { + f, err := os.Open(filename) + if err != nil { + return + } + defer f.Close() + return Decode(f) +} + +func Save(filename string, m image.Image, opt *Options) error { + f, err := os.Create(filename) + if err != nil { + return err + } + defer f.Close() + return Encode(f, m, opt) +} + +// minInt returns the smaller of x or y. +func minInt(a, b int) int { + if a <= b { + return a + } + return b +} diff --git a/vendor/github.com/chai2010/tiff/writer.go b/vendor/github.com/chai2010/tiff/writer.go new file mode 100644 index 00000000..c4771c3b --- /dev/null +++ b/vendor/github.com/chai2010/tiff/writer.go @@ -0,0 +1,44 @@ +// Copyright 2015 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package tiff + +import ( + "image" + "io" +) + +type _Writer struct { + Writer io.WriteSeeker + Header *Header + Ifd []*IFD + Cfg []image.Config + Opt []*Options + + ws *seekioWriter +} + +func _OpenWriter(w io.Writer, cfg []image.Config, opt []*Options) (p *_Writer, err error) { + return +} + +func (p *_Writer) ImageNum() int { + return len(p.Ifd) +} + +func (p *_Writer) ImageConfig(idx int) image.Config { + return p.Cfg[idx] +} + +func (p *_Writer) EncodeImage(idx int, m image.Image) (err error) { + return +} + +func (p *_Writer) Close() (err error) { + if p != nil && p.ws != nil { + err = p.ws.Close() + } + *p = _Writer{} + return +} diff --git a/vendor/github.com/chai2010/tiff/z_tiff_types_string.go b/vendor/github.com/chai2010/tiff/z_tiff_types_string.go new file mode 100644 index 00000000..bb848618 --- /dev/null +++ b/vendor/github.com/chai2010/tiff/z_tiff_types_string.go @@ -0,0 +1,792 @@ +// Copyright 2014 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Auto generated by gen_helper.go, DO NOT EDIT!!! + +package tiff + +import ( + "fmt" + "time" +) + +var _TiffTypeTable = map[TiffType]string{ + TiffType_ClassicTIFF: `TiffType_ClassicTIFF`, + TiffType_BigTIFF: `TiffType_BigTIFF`, +} + +func (p TiffType) String() string { + if name, ok := _TiffTypeTable[p]; ok { + return name + } + return fmt.Sprintf("TiffType_Unknown(%d)", uint16(p)) +} + +var _ImageTypeTable = map[ImageType]string{ + ImageType_Nil: `ImageType_Nil`, + ImageType_Bilevel: `ImageType_Bilevel`, + ImageType_BilevelInvert: `ImageType_BilevelInvert`, + ImageType_Paletted: `ImageType_Paletted`, + ImageType_Gray: `ImageType_Gray`, + ImageType_GrayInvert: `ImageType_GrayInvert`, + ImageType_RGB: `ImageType_RGB`, + ImageType_RGBA: `ImageType_RGBA`, + ImageType_NRGBA: `ImageType_NRGBA`, +} + +func (p ImageType) String() string { + if name, ok := _ImageTypeTable[p]; ok { + return name + } + return fmt.Sprintf("ImageType_Unknown(%d)", uint16(p)) +} + +var _DataTypeTable = map[DataType]string{ + DataType_Nil: `DataType_Nil`, // placeholder, invalid + DataType_Byte: `DataType_Byte`, // 8-bit unsigned integer + DataType_ASCII: `DataType_ASCII`, // 8-bit bytes w/ last byte null + DataType_Short: `DataType_Short`, // 16-bit unsigned integer + DataType_Long: `DataType_Long`, // 32-bit unsigned integer + DataType_Rational: `DataType_Rational`, // 64-bit unsigned fraction + DataType_SByte: `DataType_SByte`, // !8-bit signed integer + DataType_Undefined: `DataType_Undefined`, // !8-bit untyped data + DataType_SShort: `DataType_SShort`, // !16-bit signed integer + DataType_SLong: `DataType_SLong`, // !32-bit signed integer + DataType_SRational: `DataType_SRational`, // !64-bit signed fraction + DataType_Float: `DataType_Float`, // !32-bit IEEE floating point + DataType_Double: `DataType_Double`, // !64-bit IEEE floating point + DataType_IFD: `DataType_IFD`, // %32-bit unsigned integer (offset) + DataType_Long8: `DataType_Long8`, // BigTIFF 64-bit unsigned integer + DataType_SLong8: `DataType_SLong8`, // BigTIFF 64-bit signed integer + DataType_IFD8: `DataType_IFD8`, // BigTIFF 64-bit unsigned integer (offset) +} + +func (p DataType) String() string { + if name, ok := _DataTypeTable[p]; ok { + return name + } + return fmt.Sprintf("DataType_Unknown(%d)", uint16(p)) +} + +var _TagTypeTable = map[TagType]string{ + TagType_NewSubfileType: `TagType_NewSubfileType`, // LONG , 1, # Default=0. subfile data descriptor + TagType_SubfileType: `TagType_SubfileType`, // SHORT, 1, # kind of data in subfile + TagType_ImageWidth: `TagType_ImageWidth`, // SHORT/LONG/LONG8, 1, # Required + TagType_ImageLength: `TagType_ImageLength`, // SHORT/LONG/LONG8, 1, # Required + TagType_BitsPerSample: `TagType_BitsPerSample`, // SHORT, *, # Default=1. See SamplesPerPixel + TagType_Compression: `TagType_Compression`, // SHORT, 1, # Default=1 + TagType_PhotometricInterpretation: `TagType_PhotometricInterpretation`, // SHORT, 1, + TagType_Threshholding: `TagType_Threshholding`, // SHORT, 1, # Default=1 + TagType_CellWidth: `TagType_CellWidth`, // SHORT, 1, + TagType_CellLenght: `TagType_CellLenght`, // SHORT, 1, + TagType_FillOrder: `TagType_FillOrder`, // SHORT, 1, # Default=1 + TagType_DocumentName: `TagType_DocumentName`, // ASCII + TagType_ImageDescription: `TagType_ImageDescription`, // ASCII + TagType_Make: `TagType_Make`, // ASCII + TagType_Model: `TagType_Model`, // ASCII + TagType_StripOffsets: `TagType_StripOffsets`, // SHORT/LONG/LONG8, *, # StripsPerImage + TagType_Orientation: `TagType_Orientation`, // SHORT, 1, # Default=1 + TagType_SamplesPerPixel: `TagType_SamplesPerPixel`, // SHORT, 1, # Default=1 + TagType_RowsPerStrip: `TagType_RowsPerStrip`, // SHORT/LONG/LONG8, 1, + TagType_StripByteCounts: `TagType_StripByteCounts`, // SHORT/LONG/LONG8, *, # StripsPerImage + TagType_MinSampleValue: `TagType_MinSampleValue`, // SHORT, *, # Default=0 + TagType_MaxSampleValue: `TagType_MaxSampleValue`, // SHORT, *, # Default=2^BitsPerSample-1 + TagType_XResolution: `TagType_XResolution`, // RATIONAL, 1, # Required? + TagType_YResolution: `TagType_YResolution`, // RATIONAL, 1, # Required? + TagType_PlanarConfiguration: `TagType_PlanarConfiguration`, // SHORT, 1, # Defaule=1 + TagType_PageName: `TagType_PageName`, // ASCII + TagType_XPosition: `TagType_XPosition`, // RATIONAL, 1 + TagType_YPosition: `TagType_YPosition`, // RATIONAL, 1 + TagType_FreeOffsets: `TagType_FreeOffsets`, // LONG/LONG8, * + TagType_FreeByteCounts: `TagType_FreeByteCounts`, // LONG/LONG8, * + TagType_GrayResponseUnit: `TagType_GrayResponseUnit`, // SHORT, 1, + TagType_GrayResponseCurve: `TagType_GrayResponseCurve`, // SHORT, *, # 2**BitPerSample + TagType_T4Options: `TagType_T4Options`, // LONG, 1, # Default=0 + TagType_T6Options: `TagType_T6Options`, // LONG, 1, # Default=0 + TagType_ResolutionUnit: `TagType_ResolutionUnit`, // SHORT, 1, # Default=2 + TagType_PageNumber: `TagType_PageNumber`, // SHORT, 2, + TagType_TransferFunction: `TagType_TransferFunction`, // SHORT, *, # {1 or SamplesPerPixel}*2**BitPerSample + TagType_Software: `TagType_Software`, // ASCII + TagType_DateTime: `TagType_DateTime`, // ASCII, 20, # YYYY:MM:DD HH:MM:SS, include NULL + TagType_Artist: `TagType_Artist`, // ASCII + TagType_HostComputer: `TagType_HostComputer`, // ASCII + TagType_Predictor: `TagType_Predictor`, // SHORT, 1, # Default=1 + TagType_WhitePoint: `TagType_WhitePoint`, // RATIONAL, 2 + TagType_PrimaryChromaticities: `TagType_PrimaryChromaticities`, // RATIONAL, 6 + TagType_ColorMap: `TagType_ColorMap`, // SHORT, *, # 3*(2**BitPerSample) + TagType_HalftoneHints: `TagType_HalftoneHints`, // SHORT, 2 + TagType_TileWidth: `TagType_TileWidth`, // SHORT/LONG, 1 + TagType_TileLength: `TagType_TileLength`, // SHORT/LONG, 1 + TagType_TileOffsets: `TagType_TileOffsets`, // LONG/LONG8, *, # TilesPerImage + TagType_TileByteCounts: `TagType_TileByteCounts`, // SHORT/LONG, *, # TilesPerImage + TagType_BadFaxLines: `TagType_BadFaxLines`, // ingore # Used in the TIFF-F standard, denotes the number of 'bad' scan lines encountered by the facsimile device. + TagType_CleanFaxData: `TagType_CleanFaxData`, // ingore # Used in the TIFF-F standard, indicates if 'bad' lines encountered during reception are stored in the data, or if 'bad' lines have been replaced by the receiver. + TagType_ConsecutiveBadFaxLines: `TagType_ConsecutiveBadFaxLines`, // ingore # Used in the TIFF-F standard, denotes the maximum number of consecutive 'bad' scanlines received. + TagType_SubIFD: `TagType_SubIFD`, // IFD, * # IFD pointer + TagType_InkSet: `TagType_InkSet`, // SHORT, 1, # Default=1 + TagType_InkNames: `TagType_InkNames`, // ASCII + TagType_NumberOfInks: `TagType_NumberOfInks`, // SHORT, 1, # Default=4 + TagType_DotRange: `TagType_DotRange`, // BYTE/SHORT, # Default=[0,2^BitsPerSample-1] + TagType_TargetPrinter: `TagType_TargetPrinter`, // ASCII + TagType_ExtraSamples: `TagType_ExtraSamples`, // BYTE, 1, + TagType_SampleFormat: `TagType_SampleFormat`, // SHORT, *, # SamplesPerPixel. Default=1 + TagType_SMinSampleValue: `TagType_SMinSampleValue`, // *, *, # SamplesPerPixel, try double + TagType_SMaxSampleValue: `TagType_SMaxSampleValue`, // *, *, # SamplesPerPixel, try double + TagType_TransferRange: `TagType_TransferRange`, // SHORT, 6, + TagType_ClipPath: `TagType_ClipPath`, // ingore # Mirrors the essentials of PostScript's path creation functionality. + TagType_XClipPathUnits: `TagType_XClipPathUnits`, // ingore # The number of units that span the width of the image, in terms of integer ClipPath coordinates. + TagType_YClipPathUnits: `TagType_YClipPathUnits`, // ingore # The number of units that span the height of the image, in terms of integer ClipPath coordinates. + TagType_Indexed: `TagType_Indexed`, // ingore # Aims to broaden the support for indexed images to include support for any color space. + TagType_JPEGTables: `TagType_JPEGTables`, // ingore # JPEG quantization and/or Huffman tables. + TagType_OPIProxy: `TagType_OPIProxy`, // ingore # OPI-related. + TagType_GlobalParametersIFD: `TagType_GlobalParametersIFD`, // ingore # Used in the TIFF-FX standard to point to an IFD containing tags that are globally applicable to the complete TIFF file. + TagType_ProfileType: `TagType_ProfileType`, // ingore # Used in the TIFF-FX standard, denotes the type of data stored in this file or IFD. + TagType_FaxProfile: `TagType_FaxProfile`, // ingore # Used in the TIFF-FX standard, denotes the 'profile' that applies to this file. + TagType_CodingMethods: `TagType_CodingMethods`, // ingore # Used in the TIFF-FX standard, indicates which coding methods are used in the file. + TagType_VersionYear: `TagType_VersionYear`, // ingore # Used in the TIFF-FX standard, denotes the year of the standard specified by the FaxProfile field. + TagType_ModeNumber: `TagType_ModeNumber`, // ingore # Used in the TIFF-FX standard, denotes the mode of the standard specified by the FaxProfile field. + TagType_Decode: `TagType_Decode`, // ingore # Used in the TIFF-F and TIFF-FX standards, holds information about the ITULAB (PhotometricInterpretation = 10) encoding. + TagType_DefaultImageColor: `TagType_DefaultImageColor`, // ingore # Defined in the Mixed Raster Content part of RFC 2301, is the default color needed in areas where no image is available. + TagType_JPEGProc: `TagType_JPEGProc`, // SHORT, 1, + TagType_JPEGInterchangeFormat: `TagType_JPEGInterchangeFormat`, // LONG, 1, + TagType_JPEGInterchangeFormatLength: `TagType_JPEGInterchangeFormatLength`, // LONG, 1, + TagType_JPEGRestartInterval: `TagType_JPEGRestartInterval`, // SHORT, 1, + TagType_JPEGLosslessPredictors: `TagType_JPEGLosslessPredictors`, // SHORT, *, # SamplesPerPixel + TagType_JPEGPointTransforms: `TagType_JPEGPointTransforms`, // SHORT, *, # SamplesPerPixel + TagType_JPEGQTables: `TagType_JPEGQTables`, // LONG, *, # SamplesPerPixel + TagType_JPEGDCTables: `TagType_JPEGDCTables`, // LONG, *, # SamplesPerPixel + TagType_JPEGACTables: `TagType_JPEGACTables`, // LONG, *, # SamplesPerPixel + TagType_YCbCrCoefficients: `TagType_YCbCrCoefficients`, // RATIONAL, 3 + TagType_YCbCrSubSampling: `TagType_YCbCrSubSampling`, // SHORT, 2, # Default=[2,2] + TagType_YCbCrPositioning: `TagType_YCbCrPositioning`, // SHORT, 1, # Default=1 + TagType_ReferenceBlackWhite: `TagType_ReferenceBlackWhite`, // LONG , *, # 2*SamplesPerPixel + TagType_StripRowCounts: `TagType_StripRowCounts`, // ingore # Defined in the Mixed Raster Content part of RFC 2301, used to replace RowsPerStrip for IFDs with variable-sized strips. + TagType_XMP: `TagType_XMP`, // ingore # XML packet containing XMP metadata + TagType_ImageID: `TagType_ImageID`, // ingore # OPI-related. + TagType_ImageLayer: `TagType_ImageLayer`, // ingore # Defined in the Mixed Raster Content part of RFC 2301, used to denote the particular function of this Image in the mixed raster scheme. + TagType_Copyright: `TagType_Copyright`, // ASCII + TagType_WangAnnotation: `TagType_WangAnnotation`, // ingore # Annotation data, as used in 'Imaging for Windows'. + TagType_MDFileTag: `TagType_MDFileTag`, // ingore # Specifies the pixel data format encoding in the Molecular Dynamics GEL file format. + TagType_MDScalePixel: `TagType_MDScalePixel`, // ingore # Specifies a scale factor in the Molecular Dynamics GEL file format. + TagType_MDColorTable: `TagType_MDColorTable`, // ingore # Used to specify the conversion from 16bit to 8bit in the Molecular Dynamics GEL file format. + TagType_MDLabName: `TagType_MDLabName`, // ingore # Name of the lab that scanned this file, as used in the Molecular Dynamics GEL file format. + TagType_MDSampleInfo: `TagType_MDSampleInfo`, // ingore # Information about the sample, as used in the Molecular Dynamics GEL file format. + TagType_MDPrepDate: `TagType_MDPrepDate`, // ingore # Date the sample was prepared, as used in the Molecular Dynamics GEL file format. + TagType_MDPrepTime: `TagType_MDPrepTime`, // ingore # Time the sample was prepared, as used in the Molecular Dynamics GEL file format. + TagType_MDFileUnits: `TagType_MDFileUnits`, // ingore # Units for data in this file, as used in the Molecular Dynamics GEL file format. + TagType_ModelPixelScaleTag: `TagType_ModelPixelScaleTag`, // DOUBLE # Used in interchangeable GeoTIFF files. + TagType_IPTC: `TagType_IPTC`, // ingore # IPTC (International Press Telecommunications Council) metadata. + TagType_INGRPacketDataTag: `TagType_INGRPacketDataTag`, // ingore # Intergraph Application specific storage. + TagType_INGRFlagRegisters: `TagType_INGRFlagRegisters`, // ingore # Intergraph Application specific flags. + TagType_IrasBTransformationMatrix: `TagType_IrasBTransformationMatrix`, // DOUBLE, 17 # Originally part of Intergraph's GeoTIFF tags, but likely understood by IrasB only. + TagType_ModelTiepointTag: `TagType_ModelTiepointTag`, // DOUBLE # Originally part of Intergraph's GeoTIFF tags, but now used in interchangeable GeoTIFF files. + TagType_ModelTransformationTag: `TagType_ModelTransformationTag`, // DOUBLE, 16 # Used in interchangeable GeoTIFF files. + TagType_Photoshop: `TagType_Photoshop`, // ingore # Collection of Photoshop 'Image Resource Blocks'. + TagType_ExifIFD: `TagType_ExifIFD`, // IFD # A pointer to the Exif IFD. + TagType_ICCProfile: `TagType_ICCProfile`, // ingore # ICC profile data. + TagType_GeoKeyDirectoryTag: `TagType_GeoKeyDirectoryTag`, // SHORT, *, # >= 4 + TagType_GeoDoubleParamsTag: `TagType_GeoDoubleParamsTag`, // DOUBLE + TagType_GeoAsciiParamsTag: `TagType_GeoAsciiParamsTag`, // ASCII + TagType_GPSIFD: `TagType_GPSIFD`, // IFD # A pointer to the Exif-related GPS Info IFD. + TagType_HylaFAXFaxRecvParams: `TagType_HylaFAXFaxRecvParams`, // ingore # Used by HylaFAX. + TagType_HylaFAXFaxSubAddress: `TagType_HylaFAXFaxSubAddress`, // ingore # Used by HylaFAX. + TagType_HylaFAXFaxRecvTime: `TagType_HylaFAXFaxRecvTime`, // ingore # Used by HylaFAX. + TagType_ImageSourceData: `TagType_ImageSourceData`, // ingore # Used by Adobe Photoshop. + TagType_InteroperabilityIFD: `TagType_InteroperabilityIFD`, // IFD # A pointer to the Exif-related Interoperability IFD. + TagType_GDAL_METADATA: `TagType_GDAL_METADATA`, // ingore # Used by the GDAL library, holds an XML list of name=value 'metadata' values about the image as a whole, and about specific samples. + TagType_GDAL_NODATA: `TagType_GDAL_NODATA`, // ingore # Used by the GDAL library, contains an ASCII encoded nodata or background pixel value. + TagType_OceScanjobDescription: `TagType_OceScanjobDescription`, // ingore # Used in the Oce scanning process. + TagType_OceApplicationSelector: `TagType_OceApplicationSelector`, // ingore # Used in the Oce scanning process. + TagType_OceIdentificationNumber: `TagType_OceIdentificationNumber`, // ingore # Used in the Oce scanning process. + TagType_OceImageLogicCharacteristics: `TagType_OceImageLogicCharacteristics`, // ingore # Used in the Oce scanning process. + TagType_DNGVersion: `TagType_DNGVersion`, // ingore # Used in IFD 0 of DNG files. + TagType_DNGBackwardVersion: `TagType_DNGBackwardVersion`, // ingore # Used in IFD 0 of DNG files. + TagType_UniqueCameraModel: `TagType_UniqueCameraModel`, // ingore # Used in IFD 0 of DNG files. + TagType_LocalizedCameraModel: `TagType_LocalizedCameraModel`, // ingore # Used in IFD 0 of DNG files. + TagType_CFAPlaneColor: `TagType_CFAPlaneColor`, // ingore # Used in Raw IFD of DNG files. + TagType_CFALayout: `TagType_CFALayout`, // ingore # Used in Raw IFD of DNG files. + TagType_LinearizationTable: `TagType_LinearizationTable`, // ingore # Used in Raw IFD of DNG files. + TagType_BlackLevelRepeatDim: `TagType_BlackLevelRepeatDim`, // ingore # Used in Raw IFD of DNG files. + TagType_BlackLevel: `TagType_BlackLevel`, // ingore # Used in Raw IFD of DNG files. + TagType_BlackLevelDeltaH: `TagType_BlackLevelDeltaH`, // ingore # Used in Raw IFD of DNG files. + TagType_BlackLevelDeltaV: `TagType_BlackLevelDeltaV`, // ingore # Used in Raw IFD of DNG files. + TagType_WhiteLevel: `TagType_WhiteLevel`, // ingore # Used in Raw IFD of DNG files. + TagType_DefaultScale: `TagType_DefaultScale`, // ingore # Used in Raw IFD of DNG files. + TagType_DefaultCropOrigin: `TagType_DefaultCropOrigin`, // ingore # Used in Raw IFD of DNG files. + TagType_DefaultCropSize: `TagType_DefaultCropSize`, // ingore # Used in Raw IFD of DNG files. + TagType_ColorMatrix1: `TagType_ColorMatrix1`, // ingore # Used in IFD 0 of DNG files. + TagType_ColorMatrix2: `TagType_ColorMatrix2`, // ingore # Used in IFD 0 of DNG files. + TagType_CameraCalibration1: `TagType_CameraCalibration1`, // ingore # Used in IFD 0 of DNG files. + TagType_CameraCalibration2: `TagType_CameraCalibration2`, // ingore # Used in IFD 0 of DNG files. + TagType_ReductionMatrix1: `TagType_ReductionMatrix1`, // ingore # Used in IFD 0 of DNG files. + TagType_ReductionMatrix2: `TagType_ReductionMatrix2`, // ingore # Used in IFD 0 of DNG files. + TagType_AnalogBalance: `TagType_AnalogBalance`, // ingore # Used in IFD 0 of DNG files. + TagType_AsShotNeutral: `TagType_AsShotNeutral`, // ingore # Used in IFD 0 of DNG files. + TagType_AsShotWhiteXY: `TagType_AsShotWhiteXY`, // ingore # Used in IFD 0 of DNG files. + TagType_BaselineExposure: `TagType_BaselineExposure`, // ingore # Used in IFD 0 of DNG files. + TagType_BaselineNoise: `TagType_BaselineNoise`, // ingore # Used in IFD 0 of DNG files. + TagType_BaselineSharpness: `TagType_BaselineSharpness`, // ingore # Used in IFD 0 of DNG files. + TagType_BayerGreenSplit: `TagType_BayerGreenSplit`, // ingore # Used in Raw IFD of DNG files. + TagType_LinearResponseLimit: `TagType_LinearResponseLimit`, // ingore # Used in IFD 0 of DNG files. + TagType_CameraSerialNumber: `TagType_CameraSerialNumber`, // ingore # Used in IFD 0 of DNG files. + TagType_LensInfo: `TagType_LensInfo`, // ingore # Used in IFD 0 of DNG files. + TagType_ChromaBlurRadius: `TagType_ChromaBlurRadius`, // ingore # Used in Raw IFD of DNG files. + TagType_AntiAliasStrength: `TagType_AntiAliasStrength`, // ingore # Used in Raw IFD of DNG files. + TagType_DNGPrivateData: `TagType_DNGPrivateData`, // ingore # Used in IFD 0 of DNG files. + TagType_MakerNoteSafety: `TagType_MakerNoteSafety`, // ingore # Used in IFD 0 of DNG files. + TagType_CalibrationIlluminant1: `TagType_CalibrationIlluminant1`, // ingore # Used in IFD 0 of DNG files. + TagType_CalibrationIlluminant2: `TagType_CalibrationIlluminant2`, // ingore # Used in IFD 0 of DNG files. + TagType_BestQualityScale: `TagType_BestQualityScale`, // ingore # Used in Raw IFD of DNG files. + TagType_AliasLayerMetadata: `TagType_AliasLayerMetadata`, // ingore # Alias Sketchbook Pro layer usage description. +} + +var _TagType_TypesTable = map[TagType][]DataType{ + TagType_NewSubfileType: []DataType{DataType_Long}, + TagType_SubfileType: []DataType{DataType_Short}, + TagType_ImageWidth: []DataType{DataType_Short, DataType_Long, DataType_Long8}, + TagType_ImageLength: []DataType{DataType_Short, DataType_Long, DataType_Long8}, + TagType_BitsPerSample: []DataType{DataType_Short}, + TagType_Compression: []DataType{DataType_Short}, + TagType_PhotometricInterpretation: []DataType{DataType_Short}, + TagType_Threshholding: []DataType{DataType_Short}, + TagType_CellWidth: []DataType{DataType_Short}, + TagType_CellLenght: []DataType{DataType_Short}, + TagType_FillOrder: []DataType{DataType_Short}, + TagType_DocumentName: []DataType{DataType_ASCII}, + TagType_ImageDescription: []DataType{DataType_ASCII}, + TagType_Make: []DataType{DataType_ASCII}, + TagType_Model: []DataType{DataType_ASCII}, + TagType_StripOffsets: []DataType{DataType_Short, DataType_Long, DataType_Long8}, + TagType_Orientation: []DataType{DataType_Short}, + TagType_SamplesPerPixel: []DataType{DataType_Short}, + TagType_RowsPerStrip: []DataType{DataType_Short, DataType_Long, DataType_Long8}, + TagType_StripByteCounts: []DataType{DataType_Short, DataType_Long, DataType_Long8}, + TagType_MinSampleValue: []DataType{DataType_Short}, + TagType_MaxSampleValue: []DataType{DataType_Short}, + TagType_XResolution: []DataType{DataType_Rational}, + TagType_YResolution: []DataType{DataType_Rational}, + TagType_PlanarConfiguration: []DataType{DataType_Short}, + TagType_PageName: []DataType{DataType_ASCII}, + TagType_XPosition: []DataType{DataType_Rational}, + TagType_YPosition: []DataType{DataType_Rational}, + TagType_FreeOffsets: []DataType{DataType_Long, DataType_Long8}, + TagType_FreeByteCounts: []DataType{DataType_Long, DataType_Long8}, + TagType_GrayResponseUnit: []DataType{DataType_Short}, + TagType_GrayResponseCurve: []DataType{DataType_Short}, + TagType_T4Options: []DataType{DataType_Long}, + TagType_T6Options: []DataType{DataType_Long}, + TagType_ResolutionUnit: []DataType{DataType_Short}, + TagType_PageNumber: []DataType{DataType_Short}, + TagType_TransferFunction: []DataType{DataType_Short}, + TagType_Software: []DataType{DataType_ASCII}, + TagType_DateTime: []DataType{DataType_ASCII}, + TagType_Artist: []DataType{DataType_ASCII}, + TagType_HostComputer: []DataType{DataType_ASCII}, + TagType_Predictor: []DataType{DataType_Short}, + TagType_WhitePoint: []DataType{DataType_Rational}, + TagType_PrimaryChromaticities: []DataType{DataType_Rational}, + TagType_ColorMap: []DataType{DataType_Short}, + TagType_HalftoneHints: []DataType{DataType_Short}, + TagType_TileWidth: []DataType{DataType_Short, DataType_Long}, + TagType_TileLength: []DataType{DataType_Short, DataType_Long}, + TagType_TileOffsets: []DataType{DataType_Long, DataType_Long8}, + TagType_TileByteCounts: []DataType{DataType_Short, DataType_Long}, + TagType_SubIFD: []DataType{DataType_IFD}, + TagType_InkSet: []DataType{DataType_Short}, + TagType_InkNames: []DataType{DataType_ASCII}, + TagType_NumberOfInks: []DataType{DataType_Short}, + TagType_DotRange: []DataType{DataType_Byte, DataType_Short}, + TagType_TargetPrinter: []DataType{DataType_ASCII}, + TagType_ExtraSamples: []DataType{DataType_Byte}, + TagType_SampleFormat: []DataType{DataType_Short}, + TagType_TransferRange: []DataType{DataType_Short}, + TagType_JPEGProc: []DataType{DataType_Short}, + TagType_JPEGInterchangeFormat: []DataType{DataType_Long}, + TagType_JPEGInterchangeFormatLength: []DataType{DataType_Long}, + TagType_JPEGRestartInterval: []DataType{DataType_Short}, + TagType_JPEGLosslessPredictors: []DataType{DataType_Short}, + TagType_JPEGPointTransforms: []DataType{DataType_Short}, + TagType_JPEGQTables: []DataType{DataType_Long}, + TagType_JPEGDCTables: []DataType{DataType_Long}, + TagType_JPEGACTables: []DataType{DataType_Long}, + TagType_YCbCrCoefficients: []DataType{DataType_Rational}, + TagType_YCbCrSubSampling: []DataType{DataType_Short}, + TagType_YCbCrPositioning: []DataType{DataType_Short}, + TagType_ReferenceBlackWhite: []DataType{DataType_Long}, + TagType_Copyright: []DataType{DataType_ASCII}, + TagType_ModelPixelScaleTag: []DataType{DataType_Double}, + TagType_IrasBTransformationMatrix: []DataType{DataType_Double}, + TagType_ModelTiepointTag: []DataType{DataType_Double}, + TagType_ModelTransformationTag: []DataType{DataType_Double}, + TagType_ExifIFD: []DataType{DataType_IFD}, + TagType_GeoKeyDirectoryTag: []DataType{DataType_Short}, + TagType_GeoDoubleParamsTag: []DataType{DataType_Double}, + TagType_GeoAsciiParamsTag: []DataType{DataType_ASCII}, + TagType_GPSIFD: []DataType{DataType_IFD}, + TagType_InteroperabilityIFD: []DataType{DataType_IFD}, +} + +var _TagType_NumsTable = map[TagType][]int{ + TagType_NewSubfileType: []int{1}, + TagType_SubfileType: []int{1}, + TagType_ImageWidth: []int{1}, + TagType_ImageLength: []int{1}, + TagType_Compression: []int{1}, + TagType_PhotometricInterpretation: []int{1}, + TagType_Threshholding: []int{1}, + TagType_CellWidth: []int{1}, + TagType_CellLenght: []int{1}, + TagType_FillOrder: []int{1}, + TagType_Orientation: []int{1}, + TagType_SamplesPerPixel: []int{1}, + TagType_RowsPerStrip: []int{1}, + TagType_XResolution: []int{1}, + TagType_YResolution: []int{1}, + TagType_PlanarConfiguration: []int{1}, + TagType_XPosition: []int{1}, + TagType_YPosition: []int{1}, + TagType_GrayResponseUnit: []int{1}, + TagType_T4Options: []int{1}, + TagType_T6Options: []int{1}, + TagType_ResolutionUnit: []int{1}, + TagType_PageNumber: []int{2}, + TagType_DateTime: []int{20}, + TagType_Predictor: []int{1}, + TagType_WhitePoint: []int{2}, + TagType_PrimaryChromaticities: []int{6}, + TagType_HalftoneHints: []int{2}, + TagType_TileWidth: []int{1}, + TagType_TileLength: []int{1}, + TagType_InkSet: []int{1}, + TagType_NumberOfInks: []int{1}, + TagType_ExtraSamples: []int{1}, + TagType_TransferRange: []int{6}, + TagType_JPEGProc: []int{1}, + TagType_JPEGInterchangeFormat: []int{1}, + TagType_JPEGInterchangeFormatLength: []int{1}, + TagType_JPEGRestartInterval: []int{1}, + TagType_YCbCrCoefficients: []int{3}, + TagType_YCbCrSubSampling: []int{2}, + TagType_YCbCrPositioning: []int{1}, + TagType_IrasBTransformationMatrix: []int{17}, + TagType_ModelTransformationTag: []int{16}, +} + +type TagGetter interface { + GetNewSubfileType() (value int64, ok bool) + GetSubfileType() (value int64, ok bool) + GetImageWidth() (value int64, ok bool) + GetImageLength() (value int64, ok bool) + GetBitsPerSample() (value []int64, ok bool) + GetCompression() (value TagValue_CompressionType, ok bool) + GetPhotometricInterpretation() (value TagValue_PhotometricType, ok bool) + GetThreshholding() (value int64, ok bool) + GetCellWidth() (value int64, ok bool) + GetCellLenght() (value int64, ok bool) + GetFillOrder() (value int64, ok bool) + GetDocumentName() (value string, ok bool) + GetImageDescription() (value string, ok bool) + GetMake() (value string, ok bool) + GetModel() (value string, ok bool) + GetStripOffsets() (value []int64, ok bool) + GetOrientation() (value int64, ok bool) + GetSamplesPerPixel() (value int64, ok bool) + GetRowsPerStrip() (value int64, ok bool) + GetStripByteCounts() (value []int64, ok bool) + GetMinSampleValue() (value []int64, ok bool) + GetMaxSampleValue() (value []int64, ok bool) + GetXResolution() (value [2]int64, ok bool) + GetYResolution() (value [2]int64, ok bool) + GetPlanarConfiguration() (value int64, ok bool) + GetPageName() (value string, ok bool) + GetXPosition() (value [2]int64, ok bool) + GetYPosition() (value [2]int64, ok bool) + GetFreeOffsets() (value []int64, ok bool) + GetFreeByteCounts() (value []int64, ok bool) + GetGrayResponseUnit() (value int64, ok bool) + GetGrayResponseCurve() (value []int64, ok bool) + GetT4Options() (value int64, ok bool) + GetT6Options() (value int64, ok bool) + GetResolutionUnit() (value TagValue_ResolutionUnitType, ok bool) + GetPageNumber() (value []int64, ok bool) + GetTransferFunction() (value []int64, ok bool) + GetSoftware() (value string, ok bool) + GetDateTime() (value time.Time, ok bool) + GetArtist() (value string, ok bool) + GetHostComputer() (value string, ok bool) + GetPredictor() (value TagValue_PredictorType, ok bool) + GetWhitePoint() (value [][2]int64, ok bool) + GetPrimaryChromaticities() (value [][2]int64, ok bool) + GetColorMap() (value [][3]uint16, ok bool) + GetHalftoneHints() (value []int64, ok bool) + GetTileWidth() (value int64, ok bool) + GetTileLength() (value int64, ok bool) + GetTileOffsets() (value []int64, ok bool) + GetTileByteCounts() (value []int64, ok bool) + GetSubIFD() (value []int64, ok bool) + GetInkSet() (value int64, ok bool) + GetInkNames() (value string, ok bool) + GetNumberOfInks() (value int64, ok bool) + GetDotRange() (value []int64, ok bool) + GetTargetPrinter() (value string, ok bool) + GetExtraSamples() (value int64, ok bool) + GetSampleFormat() (value []int64, ok bool) + GetSMinSampleValue() (value []float64, ok bool) + GetSMaxSampleValue() (value []float64, ok bool) + GetTransferRange() (value []int64, ok bool) + GetJPEGProc() (value int64, ok bool) + GetJPEGInterchangeFormat() (value int64, ok bool) + GetJPEGInterchangeFormatLength() (value int64, ok bool) + GetJPEGRestartInterval() (value int64, ok bool) + GetJPEGLosslessPredictors() (value []int64, ok bool) + GetJPEGPointTransforms() (value []int64, ok bool) + GetJPEGQTables() (value []int64, ok bool) + GetJPEGDCTables() (value []int64, ok bool) + GetJPEGACTables() (value []int64, ok bool) + GetYCbCrCoefficients() (value [][2]int64, ok bool) + GetYCbCrSubSampling() (value []int64, ok bool) + GetYCbCrPositioning() (value int64, ok bool) + GetReferenceBlackWhite() (value []int64, ok bool) + GetCopyright() (value string, ok bool) + GetModelPixelScaleTag() (value []float64, ok bool) + GetIrasBTransformationMatrix() (value []float64, ok bool) + GetModelTiepointTag() (value []float64, ok bool) + GetModelTransformationTag() (value []float64, ok bool) + GetExifIFD() (value []int64, ok bool) + GetGeoKeyDirectoryTag() (value []int64, ok bool) + GetGeoDoubleParamsTag() (value []float64, ok bool) + GetGeoAsciiParamsTag() (value string, ok bool) + GetGPSIFD() (value []int64, ok bool) + GetInteroperabilityIFD() (value []int64, ok bool) + + GetUnknown(tag TagType) (value []byte, ok bool) + + private() +} + +type TagSetter interface { + SetNewSubfileType(value int64) (ok bool) + SetSubfileType(value int64) (ok bool) + SetImageWidth(value int64) (ok bool) + SetImageLength(value int64) (ok bool) + SetBitsPerSample(value []int64) (ok bool) + SetCompression(value TagValue_CompressionType) (ok bool) + SetPhotometricInterpretation(value TagValue_PhotometricType) (ok bool) + SetThreshholding(value int64) (ok bool) + SetCellWidth(value int64) (ok bool) + SetCellLenght(value int64) (ok bool) + SetFillOrder(value int64) (ok bool) + SetDocumentName(value string) (ok bool) + SetImageDescription(value string) (ok bool) + SetMake(value string) (ok bool) + SetModel(value string) (ok bool) + SetStripOffsets(value []int64) (ok bool) + SetOrientation(value int64) (ok bool) + SetSamplesPerPixel(value int64) (ok bool) + SetRowsPerStrip(value int64) (ok bool) + SetStripByteCounts(value []int64) (ok bool) + SetMinSampleValue(value []int64) (ok bool) + SetMaxSampleValue(value []int64) (ok bool) + SetXResolution(value [2]int64) (ok bool) + SetYResolution(value [2]int64) (ok bool) + SetPlanarConfiguration(value int64) (ok bool) + SetPageName(value string) (ok bool) + SetXPosition(value [2]int64) (ok bool) + SetYPosition(value [2]int64) (ok bool) + SetFreeOffsets(value []int64) (ok bool) + SetFreeByteCounts(value []int64) (ok bool) + SetGrayResponseUnit(value int64) (ok bool) + SetGrayResponseCurve(value []int64) (ok bool) + SetT4Options(value int64) (ok bool) + SetT6Options(value int64) (ok bool) + SetResolutionUnit(value TagValue_ResolutionUnitType) (ok bool) + SetPageNumber(value []int64) (ok bool) + SetTransferFunction(value []int64) (ok bool) + SetSoftware(value string) (ok bool) + SetDateTime(value time.Time) (ok bool) + SetArtist(value string) (ok bool) + SetHostComputer(value string) (ok bool) + SetPredictor(value TagValue_PredictorType) (ok bool) + SetWhitePoint(value [][2]int64) (ok bool) + SetPrimaryChromaticities(value [][2]int64) (ok bool) + SetColorMap(value [][3]uint16) (ok bool) + SetHalftoneHints(value []int64) (ok bool) + SetTileWidth(value int64) (ok bool) + SetTileLength(value int64) (ok bool) + SetTileOffsets(value []int64) (ok bool) + SetTileByteCounts(value []int64) (ok bool) + SetSubIFD(value []int64) (ok bool) + SetInkSet(value int64) (ok bool) + SetInkNames(value string) (ok bool) + SetNumberOfInks(value int64) (ok bool) + SetDotRange(value []int64) (ok bool) + SetTargetPrinter(value string) (ok bool) + SetExtraSamples(value int64) (ok bool) + SetSampleFormat(value []int64) (ok bool) + SetSMinSampleValue(value []float64) (ok bool) + SetSMaxSampleValue(value []float64) (ok bool) + SetTransferRange(value []int64) (ok bool) + SetJPEGProc(value int64) (ok bool) + SetJPEGInterchangeFormat(value int64) (ok bool) + SetJPEGInterchangeFormatLength(value int64) (ok bool) + SetJPEGRestartInterval(value int64) (ok bool) + SetJPEGLosslessPredictors(value []int64) (ok bool) + SetJPEGPointTransforms(value []int64) (ok bool) + SetJPEGQTables(value []int64) (ok bool) + SetJPEGDCTables(value []int64) (ok bool) + SetJPEGACTables(value []int64) (ok bool) + SetYCbCrCoefficients(value [][2]int64) (ok bool) + SetYCbCrSubSampling(value []int64) (ok bool) + SetYCbCrPositioning(value int64) (ok bool) + SetReferenceBlackWhite(value []int64) (ok bool) + SetCopyright(value string) (ok bool) + SetModelPixelScaleTag(value []float64) (ok bool) + SetIrasBTransformationMatrix(value []float64) (ok bool) + SetModelTiepointTag(value []float64) (ok bool) + SetModelTransformationTag(value []float64) (ok bool) + SetExifIFD(value []int64) (ok bool) + SetGeoKeyDirectoryTag(value []int64) (ok bool) + SetGeoDoubleParamsTag(value []float64) (ok bool) + SetGeoAsciiParamsTag(value string) (ok bool) + SetGPSIFD(value []int64) (ok bool) + SetInteroperabilityIFD(value []int64) (ok bool) + + SetUnknown(tag TagType, value interface{}) (ok bool) + + private() +} + +func (p TagType) String() string { + if name, ok := _TagTypeTable[p]; ok { + return name + } + return fmt.Sprintf("TagType_Unknown(%d)", uint16(p)) +} + +var _TagValue_NewSubfileTypeTable = map[TagValue_NewSubfileType]string{ + TagValue_NewSubfileType_Nil: `TagValue_NewSubfileType_Nil`, // + TagValue_NewSubfileType_Reduced: `TagValue_NewSubfileType_Reduced`, // # bit0, reduced resolution version + TagValue_NewSubfileType_Page: `TagValue_NewSubfileType_Page`, // # bit1, one page of many + TagValue_NewSubfileType_Reduced_Page: `TagValue_NewSubfileType_Reduced_Page`, // + TagValue_NewSubfileType_Mask: `TagValue_NewSubfileType_Mask`, // # bit2, transparency mask + TagValue_NewSubfileType_Reduced_Mask: `TagValue_NewSubfileType_Reduced_Mask`, // + TagValue_NewSubfileType_Page_Mask: `TagValue_NewSubfileType_Page_Mask`, // + TagValue_NewSubfileType_Reduced_Page_Mask: `TagValue_NewSubfileType_Reduced_Page_Mask`, // +} + +func (p TagValue_NewSubfileType) String() string { + if name, ok := _TagValue_NewSubfileTypeTable[p]; ok { + return name + } + return fmt.Sprintf("TagValue_NewSubfileType_Unknown(%d)", uint16(p)) +} + +var _TagValue_SubfileTypeTable = map[TagValue_SubfileType]string{ + TagValue_SubfileType_Image: `TagValue_SubfileType_Image`, // # full resolution image data + TagValue_SubfileType_ReducedImage: `TagValue_SubfileType_ReducedImage`, // # reduced size image data + TagValue_SubfileType_Page: `TagValue_SubfileType_Page`, // # one page of many +} + +func (p TagValue_SubfileType) String() string { + if name, ok := _TagValue_SubfileTypeTable[p]; ok { + return name + } + return fmt.Sprintf("TagValue_SubfileType_Unknown(%d)", uint16(p)) +} + +var _TagValue_CompressionTypeTable = map[TagValue_CompressionType]string{ + TagValue_CompressionType_Nil: `TagValue_CompressionType_Nil`, // + TagValue_CompressionType_None: `TagValue_CompressionType_None`, // + TagValue_CompressionType_CCITT: `TagValue_CompressionType_CCITT`, // + TagValue_CompressionType_G3: `TagValue_CompressionType_G3`, // # Group 3 Fax. + TagValue_CompressionType_G4: `TagValue_CompressionType_G4`, // # Group 4 Fax. + TagValue_CompressionType_LZW: `TagValue_CompressionType_LZW`, // + TagValue_CompressionType_JPEGOld: `TagValue_CompressionType_JPEGOld`, // # Superseded by cJPEG. + TagValue_CompressionType_JPEG: `TagValue_CompressionType_JPEG`, // + TagValue_CompressionType_Deflate: `TagValue_CompressionType_Deflate`, // # zlib compression. + TagValue_CompressionType_PackBits: `TagValue_CompressionType_PackBits`, // + TagValue_CompressionType_DeflateOld: `TagValue_CompressionType_DeflateOld`, // # Superseded by cDeflate. +} + +func (p TagValue_CompressionType) String() string { + if name, ok := _TagValue_CompressionTypeTable[p]; ok { + return name + } + return fmt.Sprintf("TagValue_CompressionType_Unknown(%d)", uint16(p)) +} + +var _TagValue_PhotometricTypeTable = map[TagValue_PhotometricType]string{ + TagValue_PhotometricType_WhiteIsZero: `TagValue_PhotometricType_WhiteIsZero`, // + TagValue_PhotometricType_BlackIsZero: `TagValue_PhotometricType_BlackIsZero`, // + TagValue_PhotometricType_RGB: `TagValue_PhotometricType_RGB`, // + TagValue_PhotometricType_Paletted: `TagValue_PhotometricType_Paletted`, // + TagValue_PhotometricType_TransMask: `TagValue_PhotometricType_TransMask`, // # transparency mask + TagValue_PhotometricType_CMYK: `TagValue_PhotometricType_CMYK`, // + TagValue_PhotometricType_YCbCr: `TagValue_PhotometricType_YCbCr`, // + TagValue_PhotometricType_CIELab: `TagValue_PhotometricType_CIELab`, // +} + +func (p TagValue_PhotometricType) String() string { + if name, ok := _TagValue_PhotometricTypeTable[p]; ok { + return name + } + return fmt.Sprintf("TagValue_PhotometricType_Unknown(%d)", uint16(p)) +} + +var _TagValue_PredictorTypeTable = map[TagValue_PredictorType]string{ + TagValue_PredictorType_None: `TagValue_PredictorType_None`, // + TagValue_PredictorType_Horizontal: `TagValue_PredictorType_Horizontal`, // +} + +func (p TagValue_PredictorType) String() string { + if name, ok := _TagValue_PredictorTypeTable[p]; ok { + return name + } + return fmt.Sprintf("TagValue_PredictorType_Unknown(%d)", uint16(p)) +} + +var _TagValue_ResolutionUnitTypeTable = map[TagValue_ResolutionUnitType]string{ + TagValue_ResolutionUnitType_None: `TagValue_ResolutionUnitType_None`, // + TagValue_ResolutionUnitType_PerInch: `TagValue_ResolutionUnitType_PerInch`, // # Dots per inch. + TagValue_ResolutionUnitType_PerCM: `TagValue_ResolutionUnitType_PerCM`, // # Dots per centimeter. +} + +func (p TagValue_ResolutionUnitType) String() string { + if name, ok := _TagValue_ResolutionUnitTypeTable[p]; ok { + return name + } + return fmt.Sprintf("TagValue_ResolutionUnitType_Unknown(%d)", uint16(p)) +} + +var _TagValue_SampleFormatTypeTable = map[TagValue_SampleFormatType]string{ + TagValue_SampleFormatType_Uint: `TagValue_SampleFormatType_Uint`, // + TagValue_SampleFormatType_TwoInt: `TagValue_SampleFormatType_TwoInt`, // + TagValue_SampleFormatType_Float: `TagValue_SampleFormatType_Float`, // + TagValue_SampleFormatType_Undefined: `TagValue_SampleFormatType_Undefined`, // +} + +func (p TagValue_SampleFormatType) String() string { + if name, ok := _TagValue_SampleFormatTypeTable[p]; ok { + return name + } + return fmt.Sprintf("TagValue_SampleFormatType_Unknown(%d)", uint16(p)) +} + +var _ExifIFD_TagTypeTable = map[ExifIFD_TagType]string{ + ExifIFD_TagType_ExposureTime: `ExifIFD_TagType_ExposureTime`, // ingore # Exposure time, given in seconds. + ExifIFD_TagType_FNumber: `ExifIFD_TagType_FNumber`, // ingore # The F number. + ExifIFD_TagType_ExposureProgram: `ExifIFD_TagType_ExposureProgram`, // ingore # The class of the program used by the camera to set exposure when the picture is taken. + ExifIFD_TagType_SpectralSensitivity: `ExifIFD_TagType_SpectralSensitivity`, // ingore # Indicates the spectral sensitivity of each channel of the camera used. + ExifIFD_TagType_ISOSpeedRatings: `ExifIFD_TagType_ISOSpeedRatings`, // ingore # Indicates the ISO Speed and ISO Latitude of the camera or input device as specified in ISO 12232. + ExifIFD_TagType_OECF: `ExifIFD_TagType_OECF`, // ingore # Indicates the Opto-Electric Conversion Function (OECF) specified in ISO 14524. + ExifIFD_TagType_ExifVersion: `ExifIFD_TagType_ExifVersion`, // ingore # The version of the supported Exif standard. + ExifIFD_TagType_DateTimeOriginal: `ExifIFD_TagType_DateTimeOriginal`, // ingore # The date and time when the original image data was generated. + ExifIFD_TagType_DateTimeDigitized: `ExifIFD_TagType_DateTimeDigitized`, // ingore # The date and time when the image was stored as digital data. + ExifIFD_TagType_ComponentsConfiguration: `ExifIFD_TagType_ComponentsConfiguration`, // ingore # Specific to compressed data; specifies the channels and complements PhotometricInterpretation + ExifIFD_TagType_CompressedBitsPerPixel: `ExifIFD_TagType_CompressedBitsPerPixel`, // ingore # Specific to compressed data; states the compressed bits per pixel. + ExifIFD_TagType_ShutterSpeedValue: `ExifIFD_TagType_ShutterSpeedValue`, // ingore # Shutter speed. + ExifIFD_TagType_ApertureValue: `ExifIFD_TagType_ApertureValue`, // ingore # The lens aperture. + ExifIFD_TagType_BrightnessValue: `ExifIFD_TagType_BrightnessValue`, // ingore # The value of brightness. + ExifIFD_TagType_ExposureBiasValue: `ExifIFD_TagType_ExposureBiasValue`, // ingore # The exposure bias. + ExifIFD_TagType_MaxApertureValue: `ExifIFD_TagType_MaxApertureValue`, // ingore # The smallest F number of the lens. + ExifIFD_TagType_SubjectDistance: `ExifIFD_TagType_SubjectDistance`, // ingore # The distance to the subject, given in meters. + ExifIFD_TagType_MeteringMode: `ExifIFD_TagType_MeteringMode`, // ingore # The metering mode. + ExifIFD_TagType_LightSource: `ExifIFD_TagType_LightSource`, // ingore # The kind of light source. + ExifIFD_TagType_Flash: `ExifIFD_TagType_Flash`, // ingore # Indicates the status of flash when the image was shot. + ExifIFD_TagType_FocalLength: `ExifIFD_TagType_FocalLength`, // ingore # The actual focal length of the lens, in mm. + ExifIFD_TagType_SubjectArea: `ExifIFD_TagType_SubjectArea`, // ingore # Indicates the location and area of the main subject in the overall scene. + ExifIFD_TagType_MakerNote: `ExifIFD_TagType_MakerNote`, // ingore # Manufacturer specific information. + ExifIFD_TagType_UserComment: `ExifIFD_TagType_UserComment`, // ingore # Keywords or comments on the image; complements ImageDescription. + ExifIFD_TagType_SubsecTime: `ExifIFD_TagType_SubsecTime`, // ingore # A tag used to record fractions of seconds for the DateTime tag. + ExifIFD_TagType_SubsecTimeOriginal: `ExifIFD_TagType_SubsecTimeOriginal`, // ingore # A tag used to record fractions of seconds for the DateTimeOriginal tag. + ExifIFD_TagType_SubsecTimeDigitized: `ExifIFD_TagType_SubsecTimeDigitized`, // ingore # A tag used to record fractions of seconds for the DateTimeDigitized tag. + ExifIFD_TagType_FlashpixVersion: `ExifIFD_TagType_FlashpixVersion`, // ingore # The Flashpix format version supported by a FPXR file. + ExifIFD_TagType_ColorSpace: `ExifIFD_TagType_ColorSpace`, // ingore # The color space information tag is always recorded as the color space specifier. + ExifIFD_TagType_PixelXDimension: `ExifIFD_TagType_PixelXDimension`, // ingore # Specific to compressed data; the valid width of the meaningful image. + ExifIFD_TagType_PixelYDimension: `ExifIFD_TagType_PixelYDimension`, // ingore # Specific to compressed data; the valid height of the meaningful image. + ExifIFD_TagType_RelatedSoundFile: `ExifIFD_TagType_RelatedSoundFile`, // ingore # Used to record the name of an audio file related to the image data. + ExifIFD_TagType_FlashEnergy: `ExifIFD_TagType_FlashEnergy`, // ingore # Indicates the strobe energy at the time the image is captured, as measured in Beam Candle Power Seconds + ExifIFD_TagType_SpatialFrequencyResponse: `ExifIFD_TagType_SpatialFrequencyResponse`, // ingore # Records the camera or input device spatial frequency table and SFR values in the direction of image width, image height, and diagonal direction, as specified in ISO 12233. + ExifIFD_TagType_FocalPlaneXResolution: `ExifIFD_TagType_FocalPlaneXResolution`, // ingore # Indicates the number of pixels in the image width (X) direction per FocalPlaneResolutionUnit on the camera focal plane. + ExifIFD_TagType_FocalPlaneYResolution: `ExifIFD_TagType_FocalPlaneYResolution`, // ingore # Indicates the number of pixels in the image height (Y) direction per FocalPlaneResolutionUnit on the camera focal plane. + ExifIFD_TagType_FocalPlaneResolutionUnit: `ExifIFD_TagType_FocalPlaneResolutionUnit`, // ingore # Indicates the unit for measuring FocalPlaneXResolution and FocalPlaneYResolution. + ExifIFD_TagType_SubjectLocation: `ExifIFD_TagType_SubjectLocation`, // ingore # Indicates the location of the main subject in the scene. + ExifIFD_TagType_ExposureIndex: `ExifIFD_TagType_ExposureIndex`, // ingore # Indicates the exposure index selected on the camera or input device at the time the image is captured. + ExifIFD_TagType_SensingMethod: `ExifIFD_TagType_SensingMethod`, // ingore # Indicates the image sensor type on the camera or input device. + ExifIFD_TagType_FileSource: `ExifIFD_TagType_FileSource`, // ingore # Indicates the image source. + ExifIFD_TagType_SceneType: `ExifIFD_TagType_SceneType`, // ingore # Indicates the type of scene. + ExifIFD_TagType_CFAPattern: `ExifIFD_TagType_CFAPattern`, // ingore # Indicates the color filter array (CFA) geometric pattern of the image sensor when a one-chip color area sensor is used. + ExifIFD_TagType_CustomRendered: `ExifIFD_TagType_CustomRendered`, // ingore # Indicates the use of special processing on image data, such as rendering geared to output. + ExifIFD_TagType_ExposureMode: `ExifIFD_TagType_ExposureMode`, // ingore # Indicates the exposure mode set when the image was shot. + ExifIFD_TagType_WhiteBalance: `ExifIFD_TagType_WhiteBalance`, // ingore # Indicates the white balance mode set when the image was shot. + ExifIFD_TagType_DigitalZoomRatio: `ExifIFD_TagType_DigitalZoomRatio`, // ingore # Indicates the digital zoom ratio when the image was shot. + ExifIFD_TagType_FocalLengthIn35mmFilm: `ExifIFD_TagType_FocalLengthIn35mmFilm`, // ingore # Indicates the equivalent focal length assuming a 35mm film camera, in mm. + ExifIFD_TagType_SceneCaptureType: `ExifIFD_TagType_SceneCaptureType`, // ingore # Indicates the type of scene that was shot. + ExifIFD_TagType_GainControl: `ExifIFD_TagType_GainControl`, // ingore # Indicates the degree of overall image gain adjustment. + ExifIFD_TagType_Contrast: `ExifIFD_TagType_Contrast`, // ingore # Indicates the direction of contrast processing applied by the camera when the image was shot. + ExifIFD_TagType_Saturation: `ExifIFD_TagType_Saturation`, // ingore # Indicates the direction of saturation processing applied by the camera when the image was shot. + ExifIFD_TagType_Sharpness: `ExifIFD_TagType_Sharpness`, // ingore # Indicates the direction of sharpness processing applied by the camera when the image was shot. + ExifIFD_TagType_DeviceSettingDescription: `ExifIFD_TagType_DeviceSettingDescription`, // ingore # This tag indicates information on the picture-taking conditions of a particular camera model. + ExifIFD_TagType_SubjectDistanceRange: `ExifIFD_TagType_SubjectDistanceRange`, // ingore # Indicates the distance to the subject. + ExifIFD_TagType_ImageUniqueID: `ExifIFD_TagType_ImageUniqueID`, // ingore # Indicates an identifier assigned uniquely to each image. +} + +func (p ExifIFD_TagType) String() string { + if name, ok := _ExifIFD_TagTypeTable[p]; ok { + return name + } + return fmt.Sprintf("ExifIFD_TagType_Unknown(%d)", uint16(p)) +} + +var _GPSIFD_TagTypeTable = map[GPSIFD_TagType]string{ + GPSIFD_TagType_GPSVersionID: `GPSIFD_TagType_GPSVersionID`, // ingore # Indicates the version of GPSInfoIFD. + GPSIFD_TagType_GPSLatitudeRef: `GPSIFD_TagType_GPSLatitudeRef`, // ingore # Indicates whether the latitude is north or south latitude. + GPSIFD_TagType_GPSLatitude: `GPSIFD_TagType_GPSLatitude`, // ingore # Indicates the latitude. + GPSIFD_TagType_GPSLongitudeRef: `GPSIFD_TagType_GPSLongitudeRef`, // ingore # Indicates whether the longitude is east or west longitude. + GPSIFD_TagType_GPSLongitude: `GPSIFD_TagType_GPSLongitude`, // ingore # Indicates the longitude. + GPSIFD_TagType_GPSAltitudeRef: `GPSIFD_TagType_GPSAltitudeRef`, // ingore # Indicates the altitude used as the reference altitude. + GPSIFD_TagType_GPSAltitude: `GPSIFD_TagType_GPSAltitude`, // ingore # Indicates the altitude based on the reference in GPSAltitudeRef. + GPSIFD_TagType_GPSTimeStamp: `GPSIFD_TagType_GPSTimeStamp`, // ingore # Indicates the time as UTC (Coordinated Universal Time). + GPSIFD_TagType_GPSSatellites: `GPSIFD_TagType_GPSSatellites`, // ingore # Indicates the GPS satellites used for measurements. + GPSIFD_TagType_GPSStatus: `GPSIFD_TagType_GPSStatus`, // ingore # Indicates the status of the GPS receiver when the image is recorded. + GPSIFD_TagType_GPSMeasureMode: `GPSIFD_TagType_GPSMeasureMode`, // ingore # Indicates the GPS measurement mode. + GPSIFD_TagType_GPSDOP: `GPSIFD_TagType_GPSDOP`, // ingore # Indicates the GPS DOP (data degree of precision). + GPSIFD_TagType_GPSSpeedRef: `GPSIFD_TagType_GPSSpeedRef`, // ingore # Indicates the unit used to express the GPS receiver speed of movement. + GPSIFD_TagType_GPSSpeed: `GPSIFD_TagType_GPSSpeed`, // ingore # Indicates the speed of GPS receiver movement. + GPSIFD_TagType_GPSTrackRef: `GPSIFD_TagType_GPSTrackRef`, // ingore # Indicates the reference for giving the direction of GPS receiver movement. + GPSIFD_TagType_GPSTrack: `GPSIFD_TagType_GPSTrack`, // ingore # Indicates the direction of GPS receiver movement. + GPSIFD_TagType_GPSImgDirectionRef: `GPSIFD_TagType_GPSImgDirectionRef`, // ingore # Indicates the reference for giving the direction of the image when it is captured. + GPSIFD_TagType_GPSImgDirection: `GPSIFD_TagType_GPSImgDirection`, // ingore # Indicates the direction of the image when it was captured. + GPSIFD_TagType_GPSMapDatum: `GPSIFD_TagType_GPSMapDatum`, // ingore # Indicates the geodetic survey data used by the GPS receiver. + GPSIFD_TagType_GPSDestLatitudeRef: `GPSIFD_TagType_GPSDestLatitudeRef`, // ingore # Indicates whether the latitude of the destination point is north or south latitude. + GPSIFD_TagType_GPSDestLatitude: `GPSIFD_TagType_GPSDestLatitude`, // ingore # Indicates the latitude of the destination point. + GPSIFD_TagType_GPSDestLongitudeRef: `GPSIFD_TagType_GPSDestLongitudeRef`, // ingore # Indicates whether the longitude of the destination point is east or west longitude. + GPSIFD_TagType_GPSDestLongitude: `GPSIFD_TagType_GPSDestLongitude`, // ingore # Indicates the longitude of the destination point. + GPSIFD_TagType_GPSDestBearingRef: `GPSIFD_TagType_GPSDestBearingRef`, // ingore # Indicates the reference used for giving the bearing to the destination point. + GPSIFD_TagType_GPSDestBearing: `GPSIFD_TagType_GPSDestBearing`, // ingore # Indicates the bearing to the destination point. + GPSIFD_TagType_GPSDestDistanceRef: `GPSIFD_TagType_GPSDestDistanceRef`, // ingore # Indicates the unit used to express the distance to the destination point. + GPSIFD_TagType_GPSDestDistance: `GPSIFD_TagType_GPSDestDistance`, // ingore # Indicates the distance to the destination point. + GPSIFD_TagType_GPSProcessingMethod: `GPSIFD_TagType_GPSProcessingMethod`, // ingore # A character string recording the name of the method used for location finding. + GPSIFD_TagType_GPSAreaInformation: `GPSIFD_TagType_GPSAreaInformation`, // ingore # A character string recording the name of the GPS area. + GPSIFD_TagType_GPSDateStamp: `GPSIFD_TagType_GPSDateStamp`, // ingore # A character string recording date and time information relative to UTC (Coordinated Universal Time). + GPSIFD_TagType_GPSDifferential: `GPSIFD_TagType_GPSDifferential`, // ingore # Indicates whether differential correction is applied to the GPS receiver. +} + +func (p GPSIFD_TagType) String() string { + if name, ok := _GPSIFD_TagTypeTable[p]; ok { + return name + } + return fmt.Sprintf("GPSIFD_TagType_Unknown(%d)", uint16(p)) +} + +var _InteroperabilityIFD_TagTypeTable = map[InteroperabilityIFD_TagType]string{ + InteroperabilityIFD_TagType_InteroperabilityIndex: `InteroperabilityIFD_TagType_InteroperabilityIndex`, // ingore # Indicates the identification of the Interoperability rule. +} + +func (p InteroperabilityIFD_TagType) String() string { + if name, ok := _InteroperabilityIFD_TagTypeTable[p]; ok { + return name + } + return fmt.Sprintf("InteroperabilityIFD_TagType_Unknown(%d)", uint16(p)) +} diff --git a/vendor/github.com/dimchansky/utfbom/.gitignore b/vendor/github.com/dimchansky/utfbom/.gitignore new file mode 100644 index 00000000..d7ec5ceb --- /dev/null +++ b/vendor/github.com/dimchansky/utfbom/.gitignore @@ -0,0 +1,37 @@ +# Binaries for programs and plugins +*.exe +*.dll +*.so +*.dylib +*.o +*.a + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.prof + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 +.glide/ + +# Gogland +.idea/ \ No newline at end of file diff --git a/vendor/github.com/dimchansky/utfbom/.travis.yml b/vendor/github.com/dimchansky/utfbom/.travis.yml new file mode 100644 index 00000000..77be8b34 --- /dev/null +++ b/vendor/github.com/dimchansky/utfbom/.travis.yml @@ -0,0 +1,29 @@ +language: go +sudo: false + +go: + - 1.10.x + - 1.11.x + - 1.12.x + - 1.13.x + - 1.14.x + - 1.15.x + +cache: + directories: + - $HOME/.cache/go-build + - $HOME/gopath/pkg/mod + +env: + global: + - GO111MODULE=on + +before_install: + - go get github.com/mattn/goveralls + - go get golang.org/x/tools/cmd/cover + - go get golang.org/x/tools/cmd/goimports + - go get golang.org/x/lint/golint +script: + - gofiles=$(find ./ -name '*.go') && [ -z "$gofiles" ] || unformatted=$(goimports -l $gofiles) && [ -z "$unformatted" ] || (echo >&2 "Go files must be formatted with gofmt. Following files has problem:\n $unformatted" && false) + - golint ./... # This won't break the build, just show warnings + - $HOME/gopath/bin/goveralls -service=travis-ci diff --git a/vendor/github.com/dimchansky/utfbom/LICENSE b/vendor/github.com/dimchansky/utfbom/LICENSE new file mode 100644 index 00000000..6279cb87 --- /dev/null +++ b/vendor/github.com/dimchansky/utfbom/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright (c) 2018-2020, Dmitrij Koniajev (dimchansky@gmail.com) + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/dimchansky/utfbom/README.md b/vendor/github.com/dimchansky/utfbom/README.md new file mode 100644 index 00000000..8ece2800 --- /dev/null +++ b/vendor/github.com/dimchansky/utfbom/README.md @@ -0,0 +1,66 @@ +# utfbom [![Godoc](https://godoc.org/github.com/dimchansky/utfbom?status.png)](https://godoc.org/github.com/dimchansky/utfbom) [![License](https://img.shields.io/:license-apache-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![Build Status](https://travis-ci.org/dimchansky/utfbom.svg?branch=master)](https://travis-ci.org/dimchansky/utfbom) [![Go Report Card](https://goreportcard.com/badge/github.com/dimchansky/utfbom)](https://goreportcard.com/report/github.com/dimchansky/utfbom) [![Coverage Status](https://coveralls.io/repos/github/dimchansky/utfbom/badge.svg?branch=master)](https://coveralls.io/github/dimchansky/utfbom?branch=master) + +The package utfbom implements the detection of the BOM (Unicode Byte Order Mark) and removing as necessary. It can also return the encoding detected by the BOM. + +## Installation + + go get -u github.com/dimchansky/utfbom + +## Example + +```go +package main + +import ( + "bytes" + "fmt" + "io/ioutil" + + "github.com/dimchansky/utfbom" +) + +func main() { + trySkip([]byte("\xEF\xBB\xBFhello")) + trySkip([]byte("hello")) +} + +func trySkip(byteData []byte) { + fmt.Println("Input:", byteData) + + // just skip BOM + output, err := ioutil.ReadAll(utfbom.SkipOnly(bytes.NewReader(byteData))) + if err != nil { + fmt.Println(err) + return + } + fmt.Println("ReadAll with BOM skipping", output) + + // skip BOM and detect encoding + sr, enc := utfbom.Skip(bytes.NewReader(byteData)) + fmt.Printf("Detected encoding: %s\n", enc) + output, err = ioutil.ReadAll(sr) + if err != nil { + fmt.Println(err) + return + } + fmt.Println("ReadAll with BOM detection and skipping", output) + fmt.Println() +} +``` + +Output: + +``` +$ go run main.go +Input: [239 187 191 104 101 108 108 111] +ReadAll with BOM skipping [104 101 108 108 111] +Detected encoding: UTF8 +ReadAll with BOM detection and skipping [104 101 108 108 111] + +Input: [104 101 108 108 111] +ReadAll with BOM skipping [104 101 108 108 111] +Detected encoding: Unknown +ReadAll with BOM detection and skipping [104 101 108 108 111] +``` + + diff --git a/vendor/github.com/dimchansky/utfbom/utfbom.go b/vendor/github.com/dimchansky/utfbom/utfbom.go new file mode 100644 index 00000000..77a303e5 --- /dev/null +++ b/vendor/github.com/dimchansky/utfbom/utfbom.go @@ -0,0 +1,192 @@ +// Package utfbom implements the detection of the BOM (Unicode Byte Order Mark) and removing as necessary. +// It wraps an io.Reader object, creating another object (Reader) that also implements the io.Reader +// interface but provides automatic BOM checking and removing as necessary. +package utfbom + +import ( + "errors" + "io" +) + +// Encoding is type alias for detected UTF encoding. +type Encoding int + +// Constants to identify detected UTF encodings. +const ( + // Unknown encoding, returned when no BOM was detected + Unknown Encoding = iota + + // UTF8, BOM bytes: EF BB BF + UTF8 + + // UTF-16, big-endian, BOM bytes: FE FF + UTF16BigEndian + + // UTF-16, little-endian, BOM bytes: FF FE + UTF16LittleEndian + + // UTF-32, big-endian, BOM bytes: 00 00 FE FF + UTF32BigEndian + + // UTF-32, little-endian, BOM bytes: FF FE 00 00 + UTF32LittleEndian +) + +// String returns a user-friendly string representation of the encoding. Satisfies fmt.Stringer interface. +func (e Encoding) String() string { + switch e { + case UTF8: + return "UTF8" + case UTF16BigEndian: + return "UTF16BigEndian" + case UTF16LittleEndian: + return "UTF16LittleEndian" + case UTF32BigEndian: + return "UTF32BigEndian" + case UTF32LittleEndian: + return "UTF32LittleEndian" + default: + return "Unknown" + } +} + +const maxConsecutiveEmptyReads = 100 + +// Skip creates Reader which automatically detects BOM (Unicode Byte Order Mark) and removes it as necessary. +// It also returns the encoding detected by the BOM. +// If the detected encoding is not needed, you can call the SkipOnly function. +func Skip(rd io.Reader) (*Reader, Encoding) { + // Is it already a Reader? + b, ok := rd.(*Reader) + if ok { + return b, Unknown + } + + enc, left, err := detectUtf(rd) + return &Reader{ + rd: rd, + buf: left, + err: err, + }, enc +} + +// SkipOnly creates Reader which automatically detects BOM (Unicode Byte Order Mark) and removes it as necessary. +func SkipOnly(rd io.Reader) *Reader { + r, _ := Skip(rd) + return r +} + +// Reader implements automatic BOM (Unicode Byte Order Mark) checking and +// removing as necessary for an io.Reader object. +type Reader struct { + rd io.Reader // reader provided by the client + buf []byte // buffered data + err error // last error +} + +// Read is an implementation of io.Reader interface. +// The bytes are taken from the underlying Reader, but it checks for BOMs, removing them as necessary. +func (r *Reader) Read(p []byte) (n int, err error) { + if len(p) == 0 { + return 0, nil + } + + if r.buf == nil { + if r.err != nil { + return 0, r.readErr() + } + + return r.rd.Read(p) + } + + // copy as much as we can + n = copy(p, r.buf) + r.buf = nilIfEmpty(r.buf[n:]) + return n, nil +} + +func (r *Reader) readErr() error { + err := r.err + r.err = nil + return err +} + +var errNegativeRead = errors.New("utfbom: reader returned negative count from Read") + +func detectUtf(rd io.Reader) (enc Encoding, buf []byte, err error) { + buf, err = readBOM(rd) + + if len(buf) >= 4 { + if isUTF32BigEndianBOM4(buf) { + return UTF32BigEndian, nilIfEmpty(buf[4:]), err + } + if isUTF32LittleEndianBOM4(buf) { + return UTF32LittleEndian, nilIfEmpty(buf[4:]), err + } + } + + if len(buf) > 2 && isUTF8BOM3(buf) { + return UTF8, nilIfEmpty(buf[3:]), err + } + + if (err != nil && err != io.EOF) || (len(buf) < 2) { + return Unknown, nilIfEmpty(buf), err + } + + if isUTF16BigEndianBOM2(buf) { + return UTF16BigEndian, nilIfEmpty(buf[2:]), err + } + if isUTF16LittleEndianBOM2(buf) { + return UTF16LittleEndian, nilIfEmpty(buf[2:]), err + } + + return Unknown, nilIfEmpty(buf), err +} + +func readBOM(rd io.Reader) (buf []byte, err error) { + const maxBOMSize = 4 + var bom [maxBOMSize]byte // used to read BOM + + // read as many bytes as possible + for nEmpty, n := 0, 0; err == nil && len(buf) < maxBOMSize; buf = bom[:len(buf)+n] { + if n, err = rd.Read(bom[len(buf):]); n < 0 { + panic(errNegativeRead) + } + if n > 0 { + nEmpty = 0 + } else { + nEmpty++ + if nEmpty >= maxConsecutiveEmptyReads { + err = io.ErrNoProgress + } + } + } + return +} + +func isUTF32BigEndianBOM4(buf []byte) bool { + return buf[0] == 0x00 && buf[1] == 0x00 && buf[2] == 0xFE && buf[3] == 0xFF +} + +func isUTF32LittleEndianBOM4(buf []byte) bool { + return buf[0] == 0xFF && buf[1] == 0xFE && buf[2] == 0x00 && buf[3] == 0x00 +} + +func isUTF8BOM3(buf []byte) bool { + return buf[0] == 0xEF && buf[1] == 0xBB && buf[2] == 0xBF +} + +func isUTF16BigEndianBOM2(buf []byte) bool { + return buf[0] == 0xFE && buf[1] == 0xFF +} + +func isUTF16LittleEndianBOM2(buf []byte) bool { + return buf[0] == 0xFF && buf[1] == 0xFE +} + +func nilIfEmpty(buf []byte) (res []byte) { + if len(buf) > 0 { + res = buf + } + return +} diff --git a/vendor/github.com/richardlehane/mscfb/LICENSE.txt b/vendor/github.com/richardlehane/mscfb/LICENSE.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/vendor/github.com/richardlehane/mscfb/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/richardlehane/mscfb/README.md b/vendor/github.com/richardlehane/mscfb/README.md new file mode 100644 index 00000000..724db9d6 --- /dev/null +++ b/vendor/github.com/richardlehane/mscfb/README.md @@ -0,0 +1,24 @@ +A reader for Microsoft's Compound File Binary File Format. + +Example usage: + + file, _ := os.Open("test/test.doc") + defer file.Close() + doc, err := mscfb.New(file) + if err != nil { + log.Fatal(err) + } + for entry, err := doc.Next(); err == nil; entry, err = doc.Next() { + buf := make([]byte, 512) + i, _ := doc.Read(buf) + if i > 0 { + fmt.Println(buf[:i]) + } + fmt.Println(entry.Name) + } + +The Compound File Binary File Format is also known as the Object Linking and Embedding (OLE) or Component Object Model (COM) format and was used by early MS software such as MS Office. See [http://msdn.microsoft.com/en-us/library/dd942138.aspx](http://msdn.microsoft.com/en-us/library/dd942138.aspx) for more details + +Install with `go get github.com/richardlehane/mscfb` + +[![Build Status](https://travis-ci.org/richardlehane/mscfb.png?branch=master)](https://travis-ci.org/richardlehane/mscfb) \ No newline at end of file diff --git a/vendor/github.com/richardlehane/mscfb/file.go b/vendor/github.com/richardlehane/mscfb/file.go new file mode 100644 index 00000000..36a1ba76 --- /dev/null +++ b/vendor/github.com/richardlehane/mscfb/file.go @@ -0,0 +1,525 @@ +// Copyright 2013 Richard Lehane. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mscfb + +import ( + "encoding/binary" + "io" + "os" + "time" + "unicode" + "unicode/utf16" + + "github.com/richardlehane/msoleps/types" +) + +// objectType types +const ( + unknown uint8 = 0x0 // this means unallocated - typically zeroed dir entries + storage uint8 = 0x1 // this means dir + stream uint8 = 0x2 // this means file + rootStorage uint8 = 0x5 // this means root +) + +type directoryEntryFields struct { + rawName [32]uint16 //64 bytes, unicode string encoded in UTF-16. If root, "Root Entry\0" w + nameLength uint16 //2 bytes + objectType uint8 //1 byte Must be one of the types specified above + color uint8 //1 byte Must be 0x00 RED or 0x01 BLACK + leftSibID uint32 //4 bytes, Dir? Stream ID of left sibling, if none set to NOSTREAM + rightSibID uint32 //4 bytes, Dir? Stream ID of right sibling, if none set to NOSTREAM + childID uint32 //4 bytes, Dir? Stream ID of child object, if none set to NOSTREAM + clsid types.Guid // Contains an object class GUID (must be set to zeroes for stream object) + stateBits [4]byte // user-defined flags for storage object + create types.FileTime // Windows FILETIME structure + modify types.FileTime // Windows FILETIME structure + startingSectorLoc uint32 // if a stream object, first sector location. If root, first sector of ministream + streamSize [8]byte // if a stream, size of user-defined data. If root, size of ministream +} + +func makeDirEntry(b []byte) *directoryEntryFields { + d := &directoryEntryFields{} + for i := range d.rawName { + d.rawName[i] = binary.LittleEndian.Uint16(b[i*2 : i*2+2]) + } + d.nameLength = binary.LittleEndian.Uint16(b[64:66]) + d.objectType = uint8(b[66]) + d.color = uint8(b[67]) + d.leftSibID = binary.LittleEndian.Uint32(b[68:72]) + d.rightSibID = binary.LittleEndian.Uint32(b[72:76]) + d.childID = binary.LittleEndian.Uint32(b[76:80]) + d.clsid = types.MustGuid(b[80:96]) + copy(d.stateBits[:], b[96:100]) + d.create = types.MustFileTime(b[100:108]) + d.modify = types.MustFileTime(b[108:116]) + d.startingSectorLoc = binary.LittleEndian.Uint32(b[116:120]) + copy(d.streamSize[:], b[120:128]) + return d +} + +func (r *Reader) setDirEntries() error { + c := 20 + if r.header.numDirectorySectors > 0 { + c = int(r.header.numDirectorySectors) + } + de := make([]*File, 0, c) + cycles := make(map[uint32]bool) + num := int(r.sectorSize / 128) + sn := r.header.directorySectorLoc + for sn != endOfChain { + buf, err := r.readAt(fileOffset(r.sectorSize, sn), int(r.sectorSize)) + if err != nil { + return Error{ErrRead, "directory entries read error (" + err.Error() + ")", fileOffset(r.sectorSize, sn)} + } + for i := 0; i < num; i++ { + f := &File{r: r} + f.directoryEntryFields = makeDirEntry(buf[i*128:]) + fixFile(r.header.majorVersion, f) + f.curSector = f.startingSectorLoc + de = append(de, f) + } + nsn, err := r.findNext(sn, false) + if err != nil { + return Error{ErrRead, "directory entries error finding sector (" + err.Error() + ")", int64(nsn)} + } + if nsn <= sn { + if nsn == sn || cycles[nsn] { + return Error{ErrRead, "directory entries sector cycle", int64(nsn)} + } + cycles[nsn] = true + } + sn = nsn + } + r.direntries = de + return nil +} + +func fixFile(v uint16, f *File) { + fixName(f) + if f.objectType != stream { + return + } + // if the MSCFB major version is 4, then this can be a uint64 otherwise is a uint32 and the least signficant bits can contain junk + if v > 3 { + f.Size = int64(binary.LittleEndian.Uint64(f.streamSize[:])) + } else { + f.Size = int64(binary.LittleEndian.Uint32(f.streamSize[:4])) + } +} + +func fixName(f *File) { + // From the spec: + // "The length [name] MUST be a multiple of 2, and include the terminating null character in the count. + // This length MUST NOT exceed 64, the maximum size of the Directory Entry Name field." + if f.nameLength < 4 || f.nameLength > 64 { + return + } + nlen := int(f.nameLength/2 - 1) + f.Initial = f.rawName[0] + var slen int + if !unicode.IsPrint(rune(f.Initial)) { + slen = 1 + } + f.Name = string(utf16.Decode(f.rawName[slen:nlen])) +} + +func (r *Reader) traverse() error { + r.File = make([]*File, 0, len(r.direntries)) + var ( + recurse func(int, []string) + err error + counter int + ) + recurse = func(i int, path []string) { + // prevent cycles, number of recurse calls can't exceed number of directory entries + counter++ + if counter > len(r.direntries) { + err = Error{ErrTraverse, "traversal counter overflow", int64(i)} + return + } + if i < 0 || i >= len(r.direntries) { + err = Error{ErrTraverse, "illegal traversal index", int64(i)} + return + } + file := r.direntries[i] + if file.leftSibID != noStream { + recurse(int(file.leftSibID), path) + } + r.File = append(r.File, file) + file.Path = path + if file.childID != noStream { + if i > 0 { + recurse(int(file.childID), append(path, file.Name)) + } else { + recurse(int(file.childID), path) + } + } + if file.rightSibID != noStream { + recurse(int(file.rightSibID), path) + } + } + recurse(0, []string{}) + return err +} + +// File represents a MSCFB directory entry +type File struct { + Name string // stream or directory name + Initial uint16 // the first character in the name (identifies special streams such as MSOLEPS property sets) + Path []string // file path + Size int64 // size of stream + i int64 // bytes read + curSector uint32 // next sector for Read | Write + rem int64 // offset in current sector remaining previous Read | Write + *directoryEntryFields + r *Reader +} + +type fileInfo struct{ *File } + +func (fi fileInfo) Name() string { return fi.File.Name } +func (fi fileInfo) Size() int64 { + if fi.objectType != stream { + return 0 + } + return fi.File.Size +} +func (fi fileInfo) IsDir() bool { return fi.mode().IsDir() } +func (fi fileInfo) ModTime() time.Time { return fi.Modified() } +func (fi fileInfo) Mode() os.FileMode { return fi.File.mode() } +func (fi fileInfo) Sys() interface{} { return nil } + +func (f *File) mode() os.FileMode { + if f.objectType != stream { + return os.ModeDir | 0777 + } + return 0666 +} + +// FileInfo for this directory entry. Useful for IsDir() (whether a directory entry is a stream (file) or a storage object (dir)) +func (f *File) FileInfo() os.FileInfo { + return fileInfo{f} +} + +// ID returns this directory entry's CLSID field +func (f *File) ID() string { + return f.clsid.String() +} + +// Created returns this directory entry's created field +func (f *File) Created() time.Time { + return f.create.Time() +} + +// Created returns this directory entry's modified field +func (f *File) Modified() time.Time { + return f.modify.Time() +} + +// Read this directory entry +// Returns 0, io.EOF if no stream is available (i.e. for a storage object) +func (f *File) Read(b []byte) (int, error) { + if f.Size < 1 || f.i >= f.Size { + return 0, io.EOF + } + sz := len(b) + if int64(sz) > f.Size-f.i { + sz = int(f.Size - f.i) + } + // get sectors and lengths for reads + str, err := f.stream(sz) + if err != nil { + return 0, err + } + // now read + var idx, i int + for _, v := range str { + jdx := idx + int(v[1]) + if jdx < idx || jdx > sz { + return 0, Error{ErrRead, "bad read length", int64(jdx)} + } + j, err := f.r.ra.ReadAt(b[idx:jdx], v[0]) + i = i + j + if err != nil { + f.i += int64(i) + return i, Error{ErrRead, "underlying reader fail (" + err.Error() + ")", int64(idx)} + } + idx = jdx + } + f.i += int64(i) + if i != sz { + err = Error{ErrRead, "bytes read do not match expected read size", int64(i)} + } else if i < len(b) { + err = io.EOF + } + return i, err +} + +// Write to this directory entry +// Depends on the io.ReaderAt supplied to mscfb.New() being a WriterAt too +// Returns 0, io.EOF if no stream is available (i.e. for a storage object) +func (f *File) Write(b []byte) (int, error) { + if f.Size < 1 || f.i >= f.Size { + return 0, io.EOF + } + if f.r.wa == nil { + wa, ok := f.r.ra.(io.WriterAt) + if !ok { + return 0, Error{ErrWrite, "mscfb.New must be given ReaderAt convertible to a io.WriterAt in order to write", 0} + } + f.r.wa = wa + } + sz := len(b) + if int64(sz) > f.Size-f.i { + sz = int(f.Size - f.i) + } + // get sectors and lengths for writes + str, err := f.stream(sz) + if err != nil { + return 0, err + } + // now read + var idx, i int + for _, v := range str { + jdx := idx + int(v[1]) + if jdx < idx || jdx > sz { + return 0, Error{ErrWrite, "bad write length", int64(jdx)} + } + j, err := f.r.wa.WriteAt(b[idx:jdx], v[0]) + i = i + j + if err != nil { + f.i += int64(i) + return i, Error{ErrWrite, "underlying writer fail (" + err.Error() + ")", int64(idx)} + } + idx = jdx + } + f.i += int64(i) + if i != sz { + err = Error{ErrWrite, "bytes written do not match expected write size", int64(i)} + } else if i < len(b) { + err = io.EOF + } + return i, err +} + +// ReadAt reads p bytes at offset off from start of file. Does not affect seek place for other reads/writes. +func (f *File) ReadAt(p []byte, off int64) (n int, err error) { + // memorize place + mi, mrem, mcur := f.i, f.rem, f.curSector + _, err = f.Seek(off, 0) + if err == nil { + n, err = f.Read(p) + } + f.i, f.rem, f.curSector = mi, mrem, mcur + return n, err +} + +// WriteAt reads p bytes at offset off from start of file. Does not affect seek place for other reads/writes. +func (f *File) WriteAt(p []byte, off int64) (n int, err error) { + // memorize place + mi, mrem, mcur := f.i, f.rem, f.curSector + _, err = f.Seek(off, 0) + if err == nil { + n, err = f.Write(p) + } + f.i, f.rem, f.curSector = mi, mrem, mcur + return n, err +} + +// Seek sets the offset for the next Read or Write to offset, interpreted according to whence: 0 means relative to the +// start of the file, 1 means relative to the current offset, and 2 means relative to the end. Seek returns the new +// offset relative to the start of the file and an error, if any. +func (f *File) Seek(offset int64, whence int) (int64, error) { + var abs int64 + switch whence { + default: + return 0, Error{ErrSeek, "invalid whence", int64(whence)} + case 0: + abs = offset + case 1: + abs = f.i + offset + case 2: + abs = f.Size - offset + } + switch { + case abs < 0: + return f.i, Error{ErrSeek, "can't seek before start of File", abs} + case abs >= f.Size: + return f.i, Error{ErrSeek, "can't seek past File length", abs} + case abs == f.i: + return abs, nil + case abs > f.i: + t := f.i + f.i = abs + return f.i, f.seek(abs - t) + } + if f.rem >= f.i-abs { + f.rem = f.rem - (f.i - abs) + f.i = abs + return f.i, nil + } + f.rem = 0 + f.curSector = f.startingSectorLoc + f.i = abs + return f.i, f.seek(abs) +} + +func (f *File) seek(sz int64) error { + // calculate ministream and sector size + var mini bool + var ss int64 + if f.Size < miniStreamCutoffSize { + mini = true + ss = 64 + } else { + ss = int64(f.r.sectorSize) + } + + var j int64 + var err error + // if we have a remainder in the current sector, use it first + if f.rem > 0 { + if ss-f.rem <= sz { + f.curSector, err = f.r.findNext(f.curSector, mini) + if err != nil { + return err + } + j += ss - f.rem + f.rem = 0 + if j == sz { + return nil + } + } else { + f.rem += sz + return nil + } + if f.curSector == endOfChain { + return Error{ErrRead, "unexpected early end of chain", int64(f.curSector)} + } + } + + for { + // check if we are at the last sector + if sz-j < ss { + f.rem = sz - j + return nil + } else { + j += ss + f.curSector, err = f.r.findNext(f.curSector, mini) + if err != nil { + return err + } + // we might be at the last sector if there is no remainder, if so can return + if j == sz { + return nil + } + } + } +} + +// return offsets and lengths for read or write +func (f *File) stream(sz int) ([][2]int64, error) { + // calculate ministream, cap for sector slice, and sector size + var mini bool + var l int + var ss int64 + if f.Size < miniStreamCutoffSize { + mini = true + l = sz/64 + 2 + ss = 64 + } else { + l = sz/int(f.r.sectorSize) + 2 + ss = int64(f.r.sectorSize) + } + + sectors := make([][2]int64, 0, l) + var i, j int + + // if we have a remainder from a previous read, use it first + if f.rem > 0 { + offset, err := f.r.getOffset(f.curSector, mini) + if err != nil { + return nil, err + } + if ss-f.rem >= int64(sz) { + sectors = append(sectors, [2]int64{offset + f.rem, int64(sz)}) + } else { + sectors = append(sectors, [2]int64{offset + f.rem, ss - f.rem}) + } + if ss-f.rem <= int64(sz) { + f.curSector, err = f.r.findNext(f.curSector, mini) + if err != nil { + return nil, err + } + j += int(ss - f.rem) + f.rem = 0 + } else { + f.rem += int64(sz) + } + if sectors[0][1] == int64(sz) { + return sectors, nil + } + if f.curSector == endOfChain { + return nil, Error{ErrRead, "unexpected early end of chain", int64(f.curSector)} + } + i++ + } + + for { + // emergency brake! + if i >= cap(sectors) { + return nil, Error{ErrRead, "index overruns sector length", int64(i)} + } + // grab the next offset + offset, err := f.r.getOffset(f.curSector, mini) + if err != nil { + return nil, err + } + // check if we are at the last sector + if sz-j < int(ss) { + sectors = append(sectors, [2]int64{offset, int64(sz - j)}) + f.rem = int64(sz - j) + return compressChain(sectors), nil + } else { + sectors = append(sectors, [2]int64{offset, ss}) + j += int(ss) + f.curSector, err = f.r.findNext(f.curSector, mini) + if err != nil { + return nil, err + } + // we might be at the last sector if there is no remainder, if so can return + if j == sz { + return compressChain(sectors), nil + } + } + i++ + } +} + +func compressChain(locs [][2]int64) [][2]int64 { + l := len(locs) + for i, x := 0, 0; i < l && x+1 < len(locs); i++ { + if locs[x][0]+locs[x][1] == locs[x+1][0] { + locs[x][1] = locs[x][1] + locs[x+1][1] + for j := range locs[x+1 : len(locs)-1] { + locs[x+1+j] = locs[j+x+2] + } + locs = locs[:len(locs)-1] + } else { + x += 1 + } + } + return locs +} diff --git a/vendor/github.com/richardlehane/mscfb/fuzz.go b/vendor/github.com/richardlehane/mscfb/fuzz.go new file mode 100644 index 00000000..c8aa191d --- /dev/null +++ b/vendor/github.com/richardlehane/mscfb/fuzz.go @@ -0,0 +1,35 @@ +//go:build gofuzz +// +build gofuzz + +// fuzzing with https://github.com/dvyukov/go-fuzz +package mscfb + +import ( + "bytes" + "io" +) + +// todo: replace with Fuzzing from go test package +func Fuzz(data []byte) int { + doc, err := New(bytes.NewReader(data)) + if err != nil { + if doc != nil { + panic("doc != nil on error " + err.Error()) + } + return 0 + } + buf := &bytes.Buffer{} + for entry, err := doc.Next(); ; entry, err = doc.Next() { + if err != nil { + if err == io.EOF { + return 1 + } + if entry != nil { + panic("entry != nil on error " + err.Error()) + } + } + buf.Reset() + buf.ReadFrom(entry) + } + return 1 +} diff --git a/vendor/github.com/richardlehane/mscfb/mscfb.go b/vendor/github.com/richardlehane/mscfb/mscfb.go new file mode 100644 index 00000000..41bcf47a --- /dev/null +++ b/vendor/github.com/richardlehane/mscfb/mscfb.go @@ -0,0 +1,416 @@ +// Copyright 2013 Richard Lehane. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package mscfb implements a reader for Microsoft's Compound File Binary File Format (http://msdn.microsoft.com/en-us/library/dd942138.aspx). +// +// The Compound File Binary File Format is also known as the Object Linking and Embedding (OLE) or Component Object Model (COM) format and was used by many +// early MS software such as MS Office. +// +// Example: +// +// file, _ := os.Open("test/test.doc") +// defer file.Close() +// doc, err := mscfb.New(file) +// if err != nil { +// log.Fatal(err) +// } +// for entry, err := doc.Next(); err == nil; entry, err = doc.Next() { +// buf := make([]byte, 512) +// i, _ := entry.Read(buf) +// if i > 0 { +// fmt.Println(buf[:i]) +// } +// fmt.Println(entry.Name) +// } +package mscfb + +import ( + "encoding/binary" + "io" + "strconv" + "time" +) + +func fileOffset(ss, sn uint32) int64 { + return int64((sn + 1) * ss) +} + +const ( + signature uint64 = 0xE11AB1A1E011CFD0 + miniStreamSectorSize uint32 = 64 + miniStreamCutoffSize int64 = 4096 + dirEntrySize uint32 = 128 //128 bytes +) + +const ( + maxRegSect uint32 = 0xFFFFFFFA // Maximum regular sector number + difatSect uint32 = 0xFFFFFFFC //Specifies a DIFAT sector in the FAT + fatSect uint32 = 0xFFFFFFFD // Specifies a FAT sector in the FAT + endOfChain uint32 = 0xFFFFFFFE // End of linked chain of sectors + freeSect uint32 = 0xFFFFFFFF // Speficies unallocated sector in the FAT, Mini FAT or DIFAT + maxRegStreamID uint32 = 0xFFFFFFFA // maximum regular stream ID + noStream uint32 = 0xFFFFFFFF // empty pointer +) + +const lenHeader int = 8 + 16 + 10 + 6 + 12 + 8 + 16 + 109*4 + +const sliceLimit uint32 = 64000 + +type headerFields struct { + signature uint64 + _ [16]byte //CLSID - ignore, must be null + minorVersion uint16 //Version number for non-breaking changes. This field SHOULD be set to 0x003E if the major version field is either 0x0003 or 0x0004. + majorVersion uint16 //Version number for breaking changes. This field MUST be set to either 0x0003 (version 3) or 0x0004 (version 4). + _ [2]byte //byte order - ignore, must be little endian + sectorSize uint16 //This field MUST be set to 0x0009, or 0x000c, depending on the Major Version field. This field specifies the sector size of the compound file as a power of 2. If Major Version is 3, then the Sector Shift MUST be 0x0009, specifying a sector size of 512 bytes. If Major Version is 4, then the Sector Shift MUST be 0x000C, specifying a sector size of 4096 bytes. + _ [2]byte // ministream sector size - ignore, must be 64 bytes + _ [6]byte // reserved - ignore, not used + numDirectorySectors uint32 //This integer field contains the count of the number of directory sectors in the compound file. If Major Version is 3, then the Number of Directory Sectors MUST be zero. This field is not supported for version 3 compound files. + numFatSectors uint32 //This integer field contains the count of the number of FAT sectors in the compound file. + directorySectorLoc uint32 //This integer field contains the starting sector number for the directory stream. + _ [4]byte // transaction - ignore, not used + _ [4]byte // mini stream size cutooff - ignore, must be 4096 bytes + miniFatSectorLoc uint32 //This integer field contains the starting sector number for the mini FAT. + numMiniFatSectors uint32 //This integer field contains the count of the number of mini FAT sectors in the compound file. + difatSectorLoc uint32 //This integer field contains the starting sector number for the DIFAT. + numDifatSectors uint32 //This integer field contains the count of the number of DIFAT sectors in the compound file. + initialDifats [109]uint32 //The first 109 difat sectors are included in the header +} + +func makeHeader(b []byte) *headerFields { + h := &headerFields{} + h.signature = binary.LittleEndian.Uint64(b[:8]) + h.minorVersion = binary.LittleEndian.Uint16(b[24:26]) + h.majorVersion = binary.LittleEndian.Uint16(b[26:28]) + h.sectorSize = binary.LittleEndian.Uint16(b[30:32]) + h.numDirectorySectors = binary.LittleEndian.Uint32(b[40:44]) + h.numFatSectors = binary.LittleEndian.Uint32(b[44:48]) + h.directorySectorLoc = binary.LittleEndian.Uint32(b[48:52]) + h.miniFatSectorLoc = binary.LittleEndian.Uint32(b[60:64]) + h.numMiniFatSectors = binary.LittleEndian.Uint32(b[64:68]) + h.difatSectorLoc = binary.LittleEndian.Uint32(b[68:72]) + h.numDifatSectors = binary.LittleEndian.Uint32(b[72:76]) + var idx int + for i := 76; i < 512; i = i + 4 { + h.initialDifats[idx] = binary.LittleEndian.Uint32(b[i : i+4]) + idx++ + } + return h +} + +type header struct { + *headerFields + difats []uint32 + miniFatLocs []uint32 + miniStreamLocs []uint32 // chain of sectors containing the ministream +} + +func (r *Reader) setHeader() error { + buf, err := r.readAt(0, lenHeader) + if err != nil { + return err + } + r.header = &header{headerFields: makeHeader(buf)} + // sanity check - check signature + if r.header.signature != signature { + return Error{ErrFormat, "bad signature", int64(r.header.signature)} + } + // check for legal sector size + if r.header.sectorSize == 0x0009 || r.header.sectorSize == 0x000c { + r.sectorSize = uint32(1 << r.header.sectorSize) + } else { + return Error{ErrFormat, "illegal sector size", int64(r.header.sectorSize)} + } + // check for DIFAT overflow + if r.header.numDifatSectors > 0 { + sz := (r.sectorSize / 4) - 1 + if int(r.header.numDifatSectors*sz+109) < 0 { + return Error{ErrFormat, "DIFAT int overflow", int64(r.header.numDifatSectors)} + } + if r.header.numDifatSectors*sz+109 > r.header.numFatSectors+sz { + return Error{ErrFormat, "num DIFATs exceeds FAT sectors", int64(r.header.numDifatSectors)} + } + } + // check for mini FAT overflow + if r.header.numMiniFatSectors > 0 { + if int(r.sectorSize/4*r.header.numMiniFatSectors) < 0 { + return Error{ErrFormat, "mini FAT int overflow", int64(r.header.numMiniFatSectors)} + } + if r.header.numMiniFatSectors > r.header.numFatSectors*(r.sectorSize/miniStreamSectorSize) { + return Error{ErrFormat, "num mini FATs exceeds FAT sectors", int64(r.header.numFatSectors)} + } + } + return nil +} + +func (r *Reader) setDifats() error { + r.header.difats = r.header.initialDifats[:] + // return early if no extra DIFAT sectors + if r.header.numDifatSectors == 0 { + return nil + } + sz := (r.sectorSize / 4) - 1 + // prevent creation of an arbitrarily large slice + if r.header.numDifatSectors < sliceLimit { + n := make([]uint32, 109, r.header.numDifatSectors*sz+109) + copy(n, r.header.difats) + r.header.difats = n + } + off := r.header.difatSectorLoc + cycles := make(map[uint32]bool) + for i := 0; i < int(r.header.numDifatSectors); i++ { + buf, err := r.readAt(fileOffset(r.sectorSize, off), int(r.sectorSize)) + if err != nil { + return Error{ErrFormat, "error setting DIFAT(" + err.Error() + ")", int64(off)} + } + for j := 0; j < int(sz); j++ { + r.header.difats = append(r.header.difats, binary.LittleEndian.Uint32(buf[j*4:j*4+4])) + } + // detect cycles in difat + noff := binary.LittleEndian.Uint32(buf[len(buf)-4:]) + if noff <= off { + if noff == off || cycles[noff] { + return Error{ErrRead, "cycle detected in difat", int64(noff)} + } + cycles[noff] = true + } + off = noff + } + return nil +} + +// set the ministream FAT and sector slices in the header +func (r *Reader) setMiniStream() error { + // do nothing if there is no ministream + if r.direntries[0].startingSectorLoc == endOfChain || r.header.miniFatSectorLoc == endOfChain || r.header.numMiniFatSectors == 0 { + return nil + } + // build a slice of minifat sectors (akin to the DIFAT slice) + c := int(r.header.numMiniFatSectors) + r.header.miniFatLocs = make([]uint32, c) + r.header.miniFatLocs[0] = r.header.miniFatSectorLoc + for i := 1; i < c; i++ { + loc, err := r.findNext(r.header.miniFatLocs[i-1], false) + if err != nil { + return Error{ErrFormat, "setting mini stream (" + err.Error() + ")", int64(r.header.miniFatLocs[i-1])} + } + r.header.miniFatLocs[i] = loc + } + // build a slice of ministream sectors + c = int(r.sectorSize / 4 * r.header.numMiniFatSectors) + // prevent creation of an arbitrarily large slice + if r.header.numMiniFatSectors > sliceLimit { + c = int(sliceLimit) + } + r.header.miniStreamLocs = make([]uint32, 0, c) + cycles := make(map[uint32]bool) + sn := r.direntries[0].startingSectorLoc + for sn != endOfChain { + r.header.miniStreamLocs = append(r.header.miniStreamLocs, sn) + nsn, err := r.findNext(sn, false) + if err != nil { + return Error{ErrFormat, "setting mini stream (" + err.Error() + ")", int64(sn)} + } + if nsn <= sn { + if nsn == sn || cycles[nsn] { + return Error{ErrRead, "cycle detected in mini stream", int64(nsn)} + } + cycles[nsn] = true + } + sn = nsn + } + return nil +} + +func (r *Reader) readAt(offset int64, length int) ([]byte, error) { + if r.slicer { + b, err := r.ra.(slicer).Slice(offset, length) + if err != nil { + return nil, Error{ErrRead, "slicer read error (" + err.Error() + ")", offset} + } + return b, nil + } + if length > len(r.buf) { + return nil, Error{ErrRead, "read length greater than read buffer", int64(length)} + } + if _, err := r.ra.ReadAt(r.buf[:length], offset); err != nil { + return nil, Error{ErrRead, err.Error(), offset} + } + return r.buf[:length], nil +} + +func (r *Reader) getOffset(sn uint32, mini bool) (int64, error) { + if mini { + num := r.sectorSize / 64 + sec := int(sn / num) + if sec >= len(r.header.miniStreamLocs) { + return 0, Error{ErrRead, "minisector number is outside minisector range", int64(sec)} + } + dif := sn % num + return int64((r.header.miniStreamLocs[sec]+1)*r.sectorSize + dif*64), nil + } + return fileOffset(r.sectorSize, sn), nil +} + +// check the FAT sector for the next sector in a chain +func (r *Reader) findNext(sn uint32, mini bool) (uint32, error) { + entries := r.sectorSize / 4 + index := int(sn / entries) // find position in DIFAT or minifat array + var sect uint32 + if mini { + if index < 0 || index >= len(r.header.miniFatLocs) { + return 0, Error{ErrRead, "minisector index is outside miniFAT range", int64(index)} + } + sect = r.header.miniFatLocs[index] + } else { + if index < 0 || index >= len(r.header.difats) { + return 0, Error{ErrRead, "FAT index is outside DIFAT range", int64(index)} + } + sect = r.header.difats[index] + } + fatIndex := sn % entries // find position within FAT or MiniFAT sector + offset := fileOffset(r.sectorSize, sect) + int64(fatIndex*4) + buf := make([]byte, 4) + _, err := r.ra.ReadAt(buf, offset) + if err != nil { + return 0, Error{ErrRead, "bad read finding next sector (" + err.Error() + ")", offset} + } + return binary.LittleEndian.Uint32(buf), nil +} + +// Reader provides sequential access to the contents of a MS compound file (MSCFB) +type Reader struct { + slicer bool + sectorSize uint32 + buf []byte + header *header + File []*File // File is an ordered slice of final directory entries. + direntries []*File // unordered raw directory entries + entry int + + ra io.ReaderAt + wa io.WriterAt +} + +// New returns a MSCFB reader +func New(ra io.ReaderAt) (*Reader, error) { + r := &Reader{ra: ra} + if _, ok := ra.(slicer); ok { + r.slicer = true + } else { + r.buf = make([]byte, lenHeader) + } + if err := r.setHeader(); err != nil { + return nil, err + } + // resize the buffer to 4096 if sector size isn't 512 + if !r.slicer && int(r.sectorSize) > len(r.buf) { + r.buf = make([]byte, r.sectorSize) + } + if err := r.setDifats(); err != nil { + return nil, err + } + if err := r.setDirEntries(); err != nil { + return nil, err + } + if err := r.setMiniStream(); err != nil { + return nil, err + } + if err := r.traverse(); err != nil { + return nil, err + } + return r, nil +} + +// ID returns the CLSID (class ID) field from the root directory entry +func (r *Reader) ID() string { + return r.File[0].ID() +} + +// Created returns the created field from the root directory entry +func (r *Reader) Created() time.Time { + return r.File[0].Created() +} + +// Modified returns the last modified field from the root directory entry +func (r *Reader) Modified() time.Time { + return r.File[0].Modified() +} + +// Next iterates to the next directory entry. +// This isn't necessarily an adjacent *File within the File slice, but is based on the Left Sibling, Right Sibling and Child information in directory entries. +func (r *Reader) Next() (*File, error) { + r.entry++ + if r.entry >= len(r.File) { + return nil, io.EOF + } + return r.File[r.entry], nil +} + +// Read the current directory entry +func (r *Reader) Read(b []byte) (n int, err error) { + if r.entry >= len(r.File) { + return 0, io.EOF + } + return r.File[r.entry].Read(b) +} + +// Debug provides granular information from an mscfb file to assist with debugging +func (r *Reader) Debug() map[string][]uint32 { + ret := map[string][]uint32{ + "sector size": {r.sectorSize}, + "mini fat locs": r.header.miniFatLocs, + "mini stream locs": r.header.miniStreamLocs, + "directory sector": {r.header.directorySectorLoc}, + "mini stream start/size": {r.File[0].startingSectorLoc, binary.LittleEndian.Uint32(r.File[0].streamSize[:])}, + } + for f, err := r.Next(); err == nil; f, err = r.Next() { + ret[f.Name+" start/size"] = []uint32{f.startingSectorLoc, binary.LittleEndian.Uint32(f.streamSize[:])} + } + return ret +} + +const ( + // ErrFormat reports issues with the MSCFB's header structures + ErrFormat = iota + // ErrRead reports issues attempting to read MSCFB streams + ErrRead + // ErrSeek reports seek issues + ErrSeek + // ErrWrite reports write issues + ErrWrite + // ErrTraverse reports issues attempting to traverse the child-parent-sibling relations + // between MSCFB storage objects + ErrTraverse +) + +type Error struct { + typ int + msg string + val int64 +} + +func (e Error) Error() string { + return "mscfb: " + e.msg + "; " + strconv.FormatInt(e.val, 10) +} + +// Typ gives the type of MSCFB error +func (e Error) Typ() int { + return e.typ +} + +// Slicer interface avoids a copy by obtaining a byte slice directly from the underlying reader +type slicer interface { + Slice(offset int64, length int) ([]byte, error) +} diff --git a/vendor/github.com/richardlehane/msoleps/LICENSE.txt b/vendor/github.com/richardlehane/msoleps/LICENSE.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/vendor/github.com/richardlehane/msoleps/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/richardlehane/msoleps/types/currency.go b/vendor/github.com/richardlehane/msoleps/types/currency.go new file mode 100644 index 00000000..01b9c89e --- /dev/null +++ b/vendor/github.com/richardlehane/msoleps/types/currency.go @@ -0,0 +1,43 @@ +// Copyright 2014 Richard Lehane. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "encoding/binary" + "strconv" +) + +//The CURRENCY type specifies currency information. It is represented as an 8-byte integer, scaled by 10,000, to give a fixed-point number with 15 digits to the left of the decimal point, and four digits to the right. This representation provides a range of 922337203685477.5807 to –922337203685477.5808. For example, $5.25 is stored as the value 52500. + +type Currency int64 + +func (c Currency) String() string { + return "$" + strconv.FormatFloat(float64(c)/10000, 'f', -1, 64) +} + +func (c Currency) Type() string { + return "Currency" +} + +func (c Currency) Length() int { + return 8 +} + +func MakeCurrency(b []byte) (Type, error) { + if len(b) < 8 { + return Currency(0), ErrType + } + return Currency(binary.LittleEndian.Uint64(b[:8])), nil +} diff --git a/vendor/github.com/richardlehane/msoleps/types/date.go b/vendor/github.com/richardlehane/msoleps/types/date.go new file mode 100644 index 00000000..364e551a --- /dev/null +++ b/vendor/github.com/richardlehane/msoleps/types/date.go @@ -0,0 +1,49 @@ +// Copyright 2014 Richard Lehane. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "encoding/binary" + "time" +) + +// http://msdn.microsoft.com/en-us/library/cc237601.aspx +type Date float64 + +func (d Date) Time() time.Time { + start := time.Date(1899, 12, 30, 0, 0, 0, 0, time.UTC) + day := float64(time.Hour * 24) + dur := time.Duration(day * float64(d)) + return start.Add(dur) +} + +func (d Date) String() string { + return d.Time().String() +} + +func (d Date) Type() string { + return "Date" +} + +func (d Date) Length() int { + return 8 +} + +func MakeDate(b []byte) (Type, error) { + if len(b) < 8 { + return Date(0), ErrType + } + return Date(binary.LittleEndian.Uint64(b[:8])), nil +} diff --git a/vendor/github.com/richardlehane/msoleps/types/decimal.go b/vendor/github.com/richardlehane/msoleps/types/decimal.go new file mode 100644 index 00000000..090e5ffa --- /dev/null +++ b/vendor/github.com/richardlehane/msoleps/types/decimal.go @@ -0,0 +1,65 @@ +// Copyright 2014 Richard Lehane. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "encoding/binary" + "math" + "math/big" +) + +// http://msdn.microsoft.com/en-us/library/cc237603.aspx +type Decimal struct { + res [2]byte + scale byte + sign byte + high32 uint32 + low64 uint64 +} + +func (d Decimal) Type() string { + return "Decimal" +} + +func (d Decimal) Length() int { + return 16 +} + +func (d Decimal) String() string { + h, l, b := new(big.Int), new(big.Int), new(big.Int) + l.SetUint64(d.low64) + h.Lsh(big.NewInt(int64(d.high32)), 64) + b.Add(h, l) + q, f, r := new(big.Rat), new(big.Rat), new(big.Rat) + q.SetFloat64(math.Pow10(int(d.scale))) + r.Quo(f.SetInt(b), q) + if d.sign == 0x80 { + r.Neg(r) + } + return r.FloatString(20) +} + +func MakeDecimal(b []byte) (Type, error) { + if len(b) < 16 { + return Decimal{}, ErrType + } + return Decimal{ + res: [2]byte{b[0], b[1]}, + scale: b[2], + sign: b[3], + high32: binary.LittleEndian.Uint32(b[4:8]), + low64: binary.LittleEndian.Uint64(b[8:16]), + }, nil +} diff --git a/vendor/github.com/richardlehane/msoleps/types/filetime.go b/vendor/github.com/richardlehane/msoleps/types/filetime.go new file mode 100644 index 00000000..c1060ee9 --- /dev/null +++ b/vendor/github.com/richardlehane/msoleps/types/filetime.go @@ -0,0 +1,70 @@ +// Copyright 2014 Richard Lehane. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "encoding/binary" + "time" +) + +// Win FILETIME type +// http://msdn.microsoft.com/en-us/library/cc230324.aspx +type FileTime struct { + Low uint32 // Windows FILETIME structure + High uint32 // Windows FILETIME structure +} + +const ( + tick uint64 = 10000000 + gregToUnix uint64 = 11644473600 +) + +func winToUnix(low, high uint32) int64 { + gregTime := ((uint64(high) << 32) + uint64(low)) / tick + if gregTime < gregToUnix { + return 0 + } + return int64(gregTime - gregToUnix) +} + +func (f FileTime) Time() time.Time { + return time.Unix(winToUnix(f.Low, f.High), 0) +} + +func (f FileTime) String() string { + return f.Time().String() +} + +func (f FileTime) Type() string { + return "FileTime" +} + +func (f FileTime) Length() int { + return 8 +} + +func MakeFileTime(b []byte) (Type, error) { + if len(b) < 8 { + return FileTime{}, ErrType + } + return MustFileTime(b), nil +} + +func MustFileTime(b []byte) FileTime { + return FileTime{ + Low: binary.LittleEndian.Uint32(b[:4]), + High: binary.LittleEndian.Uint32(b[4:8]), + } +} diff --git a/vendor/github.com/richardlehane/msoleps/types/guid.go b/vendor/github.com/richardlehane/msoleps/types/guid.go new file mode 100644 index 00000000..86bb6449 --- /dev/null +++ b/vendor/github.com/richardlehane/msoleps/types/guid.go @@ -0,0 +1,209 @@ +// Copyright 2014 Richard Lehane. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "encoding/binary" + "encoding/hex" + "errors" + "strings" +) + +// Win GUID and UUID type +// http://msdn.microsoft.com/en-us/library/cc230326.aspx +type Guid struct { + DataA uint32 + DataB uint16 + DataC uint16 + DataD [8]byte +} + +func (g Guid) String() string { + buf := make([]byte, 8) + binary.BigEndian.PutUint32(buf[:4], g.DataA) + binary.BigEndian.PutUint16(buf[4:6], g.DataB) + binary.BigEndian.PutUint16(buf[6:], g.DataC) + return strings.ToUpper("{" + + hex.EncodeToString(buf[:4]) + + "-" + + hex.EncodeToString(buf[4:6]) + + "-" + + hex.EncodeToString(buf[6:]) + + "-" + + hex.EncodeToString(g.DataD[:2]) + + "-" + + hex.EncodeToString(g.DataD[2:]) + + "}") +} + +func (g Guid) Type() string { + return "Guid" +} + +func (g Guid) Length() int { + return 16 +} + +func GuidFromString(str string) (Guid, error) { + gerr := "Invalid GUID: expecting in format {F29F85E0-4FF9-1068-AB91-08002B27B3D9}, got " + str + if len(str) != 38 { + return Guid{}, errors.New(gerr + "; bad length, should be 38 chars") + } + trimmed := strings.Trim(str, "{}") + parts := strings.Split(trimmed, "-") + if len(parts) != 5 { + return Guid{}, errors.New(gerr + "; expecting should five '-' separators") + } + buf, err := hex.DecodeString(strings.Join(parts, "")) + if err != nil { + return Guid{}, errors.New(gerr + "; error decoding hex: " + err.Error()) + } + return makeGuid(buf, binary.BigEndian), nil +} + +func MakeGuid(b []byte) (Type, error) { + if len(b) < 16 { + return Guid{}, ErrType + } + return makeGuid(b, binary.LittleEndian), nil +} + +func makeGuid(b []byte, order binary.ByteOrder) Guid { + g := Guid{ + DataA: order.Uint32(b[:4]), + DataB: order.Uint16(b[4:6]), + DataC: order.Uint16(b[6:8]), + DataD: [8]byte{}, + } + copy(g.DataD[:], b[8:]) + return g +} + +func MustGuidFromString(str string) Guid { + g, err := GuidFromString(str) + if err != nil { + panic(err) + } + return g +} + +func MustGuid(b []byte) Guid { + return makeGuid(b, binary.LittleEndian) +} + +func GuidFromName(n string) (Guid, error) { + n = strings.ToLower(n) + buf, err := charConvert([]byte(n)) + if err != nil { + return Guid{}, err + } + return makeGuid(buf, binary.LittleEndian), nil +} + +func charConvert(in []byte) ([]byte, error) { + if len(in) != 26 { + return nil, errors.New("invalid GUID: expecting 26 characters") + } + out := make([]byte, 16) + var idx, shift uint + var b byte + for _, v := range in { + this, ok := characterMapping[v] + if !ok { + return nil, errors.New("invalid Guid: invalid character") + } + b = b | this<= 3 { + out[idx] = b + idx++ + b = this >> (8 - shift) // write any remainder back to b, or 0 if shift is 3 + } + shift = shift + 5 + if shift > 7 { + shift = shift - 8 + } + } + return out, nil +} + +const ( + charA byte = iota + charB + charC + charD + charE + charF + charG + charH + charI + charJ + charK + charL + charM + charN + charO + charP + charQ + charR + charS + charT + charU + charV + charW + charX + charY + charZ + char0 + char1 + char2 + char3 + char4 + char5 +) + +var characterMapping = map[byte]byte{ + 'a': charA, + 'b': charB, + 'c': charC, + 'd': charD, + 'e': charE, + 'f': charF, + 'g': charG, + 'h': charH, + 'i': charI, + 'j': charJ, + 'k': charK, + 'l': charL, + 'm': charM, + 'n': charN, + 'o': charO, + 'p': charP, + 'q': charQ, + 'r': charR, + 's': charS, + 't': charT, + 'u': charU, + 'v': charV, + 'w': charW, + 'x': charX, + 'y': charY, + 'z': charZ, + '0': char0, + '1': char1, + '2': char2, + '3': char3, + '4': char4, + '5': char5, +} diff --git a/vendor/github.com/richardlehane/msoleps/types/numeric.go b/vendor/github.com/richardlehane/msoleps/types/numeric.go new file mode 100644 index 00000000..0ddc3875 --- /dev/null +++ b/vendor/github.com/richardlehane/msoleps/types/numeric.go @@ -0,0 +1,274 @@ +// Copyright 2014 Richard Lehane. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "encoding/binary" + "strconv" +) + +type Null struct{} + +func (i Null) Type() string { + return "Null" +} + +func (i Null) Length() int { + return 0 +} + +func (i Null) String() string { + return "" +} + +type Bool bool + +func (i Bool) Type() string { + return "Boolean" +} + +func (i Bool) Length() int { + return 2 +} + +func (i Bool) String() string { + if i { + return "true" + } + return "false" +} + +func MakeBool(b []byte) (Type, error) { + if len(b) < 2 { + return Bool(false), ErrType + } + switch binary.LittleEndian.Uint16(b[:2]) { + case 0xFFFF: + return Bool(true), nil + case 0x0000: + return Bool(false), nil + } + return Bool(false), ErrType +} + +type I1 int8 + +func (i I1) Type() string { + return "Int8" +} + +func (i I1) String() string { + return strconv.Itoa(int(i)) +} + +func (i I1) Length() int { + return 1 +} + +func MakeI1(b []byte) (Type, error) { + if len(b) < 1 { + return I1(0), ErrType + } + return I1(b[0]), nil +} + +type I2 int16 + +func (i I2) Type() string { + return "Int16" +} + +func (i I2) Length() int { + return 2 +} + +func (i I2) String() string { + return strconv.Itoa(int(i)) +} + +func MakeI2(b []byte) (Type, error) { + if len(b) < 2 { + return I2(0), ErrType + } + return I2(binary.LittleEndian.Uint16(b[:2])), nil +} + +type I4 int32 + +func (i I4) Type() string { + return "Int32" +} + +func (i I4) Length() int { + return 4 +} + +func (i I4) String() string { + return strconv.Itoa(int(i)) +} + +func MakeI4(b []byte) (Type, error) { + if len(b) < 4 { + return I4(0), ErrType + } + return I4(binary.LittleEndian.Uint32(b[:4])), nil +} + +type I8 int64 + +func (i I8) Type() string { + return "Int64" +} + +func (i I8) Length() int { + return 8 +} + +func (i I8) String() string { + return strconv.FormatInt(int64(i), 10) +} + +func MakeI8(b []byte) (Type, error) { + if len(b) < 8 { + return I8(0), ErrType + } + return I8(binary.LittleEndian.Uint64(b[:8])), nil +} + +type UI1 uint8 + +func (i UI1) Type() string { + return "Uint8" +} + +func (i UI1) Length() int { + return 1 +} + +func (i UI1) String() string { + return strconv.Itoa(int(i)) +} + +func MakeUI1(b []byte) (Type, error) { + if len(b) < 1 { + return UI1(0), ErrType + } + return UI1(b[0]), nil +} + +type UI2 uint16 + +func (i UI2) Type() string { + return "Uint16" +} + +func (i UI2) Length() int { + return 2 +} + +func (i UI2) String() string { + return strconv.Itoa(int(i)) +} + +func MakeUI2(b []byte) (Type, error) { + if len(b) < 2 { + return UI2(0), ErrType + } + return UI2(binary.LittleEndian.Uint16(b[:2])), nil +} + +type UI4 uint32 + +func (i UI4) Type() string { + return "Uint32" +} + +func (i UI4) Length() int { + return 4 +} + +func (i UI4) String() string { + return strconv.FormatUint(uint64(i), 10) +} + +func MakeUI4(b []byte) (Type, error) { + if len(b) < 4 { + return UI4(0), ErrType + } + return UI4(binary.LittleEndian.Uint32(b[:4])), nil +} + +type UI8 uint64 + +func (i UI8) Type() string { + return "Uint64" +} + +func (i UI8) Length() int { + return 8 +} + +func (i UI8) String() string { + return strconv.FormatUint(uint64(i), 10) +} + +func MakeUI8(b []byte) (Type, error) { + if len(b) < 8 { + return UI8(0), ErrType + } + return UI8(binary.LittleEndian.Uint64(b[:8])), nil +} + +type R4 float32 + +func (r R4) Type() string { + return "Float32" +} + +func (r R4) Length() int { + return 4 +} + +func (r R4) String() string { + return strconv.FormatFloat(float64(r), 'f', -1, 32) +} + +func MakeR4(b []byte) (Type, error) { + if len(b) < 4 { + return R4(0), ErrType + } + return R4(binary.LittleEndian.Uint32(b[:4])), nil +} + +type R8 float64 + +func (r R8) Type() string { + return "Float64" +} + +func (r R8) Length() int { + return 8 +} + +func (r R8) String() string { + return strconv.FormatFloat(float64(r), 'f', -1, 64) +} + +func MakeR8(b []byte) (Type, error) { + if len(b) < 8 { + return R8(0), ErrType + } + return R8(binary.LittleEndian.Uint64(b[:8])), nil +} diff --git a/vendor/github.com/richardlehane/msoleps/types/strings.go b/vendor/github.com/richardlehane/msoleps/types/strings.go new file mode 100644 index 00000000..20ec7c01 --- /dev/null +++ b/vendor/github.com/richardlehane/msoleps/types/strings.go @@ -0,0 +1,270 @@ +// Copyright 2014 Richard Lehane. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "encoding/binary" + "strings" + "unicode/utf16" +) + +func nullTerminated(s string) string { + return s[:strings.Index(s, "\x00")] +} + +type UnicodeString []uint16 + +func (s UnicodeString) Type() string { + return "UnicodeString" +} + +func (s UnicodeString) Length() int { + return 4 + len(s)*2 +} + +func (s UnicodeString) String() string { + if len(s) == 0 { + return "" + } + return nullTerminated(string(utf16.Decode(s))) +} + +func MakeUnicode(b []byte) (Type, error) { + if len(b) < 4 { + return UnicodeString{}, ErrType + } + l := int(binary.LittleEndian.Uint32(b[:4])) + if l == 0 { + return UnicodeString{}, nil + } + if len(b) < l*2+4 { + return UnicodeString{}, ErrType + } + s := make(UnicodeString, l) + for i := range s { + start := i*2 + 4 + s[i] = binary.LittleEndian.Uint16(b[start : start+2]) + } + return s, nil +} + +type CodeString struct { + id CodePageID + Chars []byte +} + +func (s *CodeString) SetId(i CodePageID) { + s.id = i +} + +func (s *CodeString) Encoding() string { + return CodePageIDs[s.id] +} + +func (s *CodeString) Type() string { + return "CodeString" +} + +func (s *CodeString) Length() int { + return 4 + len(s.Chars) +} + +func (s *CodeString) String() string { + if len(s.Chars) == 0 { + return "" + } + if s.id == 1200 { + chars := make([]uint16, len(s.Chars)/2) + for i := range chars { + chars[i] = binary.LittleEndian.Uint16(s.Chars[i*2 : i*2+2]) + } + return nullTerminated(string(utf16.Decode(chars))) + } + return nullTerminated(string(s.Chars)) +} + +func MakeCodeString(b []byte) (Type, error) { + if len(b) < 4 { + return &CodeString{}, ErrType + } + s := &CodeString{} + l := int(binary.LittleEndian.Uint32(b[:4])) + if l == 0 { + return s, nil + } + if len(b) < l+4 { + return s, ErrType + } + s.Chars = make([]byte, l) + copy(s.Chars, b[4:l+4]) + return s, nil +} + +type CodePageID uint16 + +var CodePageIDs map[CodePageID]string = map[CodePageID]string{ + 37: "IBM037 - IBM EBCDIC US-Canada", + 437: "IBM437 - OEM United States", + 500: "IBM500 - IBM EBCDIC International", + 708: "ASMO-708 - Arabic (ASMO 708)", + 709: "Arabic (ASMO-449+, BCON V4)", + 710: "Arabic - Transparent Arabic", + 720: "DOS-720 - Arabic (Transparent ASMO); Arabic (DOS)", + 737: "ibm737 - OEM Greek (formerly 437G); Greek (DOS)", + 775: "ibm775 - OEM Baltic; Baltic (DOS)", + 850: "ibm850 - OEM Multilingual Latin 1; Western European (DOS)", + 852: "ibm852 - OEM Latin 2; Central European (DOS)", + 855: "IBM855 - OEM Cyrillic (primarily Russian)", + 857: "ibm857 - OEM Turkish; Turkish (DOS)", + 858: "IBM00858 - OEM Multilingual Latin 1 + Euro symbol", + 860: "IBM860 - OEM Portuguese; Portuguese (DOS)", + 861: "ibm861 - OEM Icelandic; Icelandic (DOS)", + 862: "DOS-862 - OEM Hebrew; Hebrew (DOS)", + 863: "IBM863 - OEM French Canadian; French Canadian (DOS)", + 864: "IBM864 - OEM Arabic; Arabic (864)", + 865: "IBM865 - OEM Nordic; Nordic (DOS)", + 866: "cp866 - OEM Russian; Cyrillic (DOS)", + 869: "ibm869 - OEM Modern Greek; Greek, Modern (DOS)", + 870: "IBM870 - IBM EBCDIC Multilingual/ROECE (Latin 2); IBM EBCDIC Multilingual Latin 2", + 874: "windows-874 - ANSI/OEM Thai (ISO 8859-11); Thai (Windows)", + 875: "cp875 - IBM EBCDIC Greek Modern", + 932: "shift_jis - ANSI/OEM Japanese; Japanese (Shift-JIS)", + 936: "gb2312 - ANSI/OEM Simplified Chinese (PRC, Singapore); Chinese Simplified (GB2312)", + 949: "ks_c_5601-1987 - ANSI/OEM Korean (Unified Hangul Code)", + 950: "big5 - ANSI/OEM Traditional Chinese (Taiwan; Hong Kong SAR, PRC); Chinese Traditional (Big5)", + 1026: "IBM1026 - IBM EBCDIC Turkish (Latin 5)", + 1047: "IBM01047 - BM EBCDIC Latin 1/Open System", + 1140: "IBM01140 - IBM EBCDIC US-Canada (037 + Euro symbol); IBM EBCDIC (US-Canada-Euro)", + 1141: "IBM01141 - IBM EBCDIC Germany (20273 + Euro symbol); IBM EBCDIC (Germany-Euro)", + 1142: "IBM01142 - IBM EBCDIC Denmark-Norway (20277 + Euro symbol); IBM EBCDIC (Denmark-Norway-Euro)", + 1143: "IBM01143 - IBM EBCDIC Finland-Sweden (20278 + Euro symbol); IBM EBCDIC (Finland-Sweden-Euro)", + 1144: "IBM01144 - IBM EBCDIC Italy (20280 + Euro symbol); IBM EBCDIC (Italy-Euro)", + 1145: "IBM01145 - IBM EBCDIC Latin America-Spain (20284 + Euro symbol); IBM EBCDIC (Spain-Euro)", + 1146: "IBM01146 - IBM EBCDIC United Kingdom (20285 + Euro symbol); IBM EBCDIC (UK-Euro)", + 1147: "IBM01147 - IBM EBCDIC France (20297 + Euro symbol); IBM EBCDIC (France-Euro)", + 1148: "IBM01148 - IBM EBCDIC International (500 + Euro symbol); IBM EBCDIC (International-Euro)", + 1149: "IBM01149 - IBM EBCDIC Icelandic (20871 + Euro symbol); IBM EBCDIC (Icelandic-Euro)", + 1200: "utf-16 - Unicode UTF-16, little endian byte order (BMP of ISO 10646); available only to managed applications", + 1201: "unicodeFFFE - Unicode UTF-16, big endian byte order; available only to managed applications", + 1250: "windows-1250 - ANSI Central European; Central European (Windows)", + 1251: "windows-1251 - ANSI Cyrillic; Cyrillic (Windows)", + 1252: "windows-1252 - ANSI Latin 1; Western European (Windows)", + 1253: "windows-1253 - ANSI Greek; Greek (Windows)", + 1254: "windows-1254 - ANSI Turkish; Turkish (Windows)", + 1255: "windows-1255 - ANSI Hebrew; Hebrew (Windows)", + 1256: "windows-1256 - ANSI Arabic; Arabic (Windows)", + 1257: "windows-1257 - ANSI Baltic; Baltic (Windows)", + 1258: "windows-1258 - ANSI/OEM Vietnamese; Vietnamese (Windows)", + 1361: "Johab - Korean (Johab)", + 10000: "macintosh - MAC Roman; Western European (Mac)", + 10001: "x-mac-japanese - Japanese (Mac)", + 10002: "x-mac-chinesetrad - MAC Traditional Chinese (Big5); Chinese Traditional (Mac)", + 10003: "x-mac-korean - Korean (Mac)", + 10004: "x-mac-arabic - Arabic (Mac)", + 10005: "x-mac-hebrew - Hebrew (Mac)", + 10006: "x-mac-greek - Greek (Mac)", + 10007: "x-mac-cyrillic - Cyrillic (Mac)", + 10008: "x-mac-chinesesimp - MAC Simplified Chinese (GB 2312); Chinese Simplified (Mac)", + 10010: "x-mac-romanian - Romanian (Mac)", + 10017: "x-mac-ukrainian - Ukrainian (Mac)", + 10021: "x-mac-thai - Thai (Mac)", + 10029: "x-mac-ce - MAC Latin 2; Central European (Mac)", + 10079: "x-mac-icelandic - Icelandic (Mac)", + 10081: "x-mac-turkish - Turkish (Mac)", + 10082: "x-mac-croatian - Croatian (Mac)", + 12000: "utf-32 - Unicode UTF-32, little endian byte order; available only to managed applications", + 12001: "utf-32BE - Unicode UTF-32, big endian byte order; available only to managed applications", + 20000: "x-Chinese_CNS - CNS Taiwan; Chinese Traditional (CNS)", + 20001: "x-cp20001 - TCA Taiwan", + 20002: "x_Chinese-Eten - Eten Taiwan; Chinese Traditional (Eten)", + 20003: "x-cp20003 - IBM5550 Taiwan", + 20004: "x-cp20004 - TeleText Taiwan", + 20005: "x-cp20005 - Wang Taiwan", + 20105: "x-IA5 - IA5 (IRV International Alphabet No. 5, 7-bit); Western European (IA5)", + 20106: "x-IA5-German - IA5 German (7-bit)", + 20107: "x-IA5-Swedish - IA5 Swedish (7-bit)", + 20108: "x-IA5-Norwegian - IA5 Norwegian (7-bit)", + 20127: "us-ascii - US-ASCII (7-bit)", + 20261: "x-cp20261 - T.61", + 20269: "x-cp20269 - ISO 6937 Non-Spacing Accent", + 20273: "IBM273 - IBM EBCDIC Germany", + 20277: "IBM277 - IBM EBCDIC Denmark-Norway", + 20278: "IBM278 - IBM EBCDIC Finland-Sweden", + 20280: "IBM280 - IBM EBCDIC Italy", + 20284: "IBM284 - IBM EBCDIC Latin America-Spain", + 20285: "IBM285 - IBM EBCDIC United Kingdom", + 20290: "IBM290 - IBM EBCDIC Japanese Katakana Extended", + 20297: "IBM297 - IBM EBCDIC France", + 20420: "IBM420 - IBM EBCDIC Arabic", + 20423: "IBM423 - IBM EBCDIC Greek", + 20424: "IBM424 - IBM EBCDIC Hebrew", + 20833: "x-EBCDIC-KoreanExtended - IBM EBCDIC Korean Extended", + 20838: "IBM-Thai - IBM EBCDIC Thai", + 20866: "koi8-r - Russian (KOI8-R); Cyrillic (KOI8-R)", + 20871: "IBM871 - IBM EBCDIC Icelandic", + 20880: "IBM880 - IBM EBCDIC Cyrillic Russian", + 20905: "IBM905 - IBM EBCDIC Turkish", + 20924: "IBM00924 - IBM EBCDIC Latin 1/Open System (1047 + Euro symbol)", + 20932: "EUC-JP - Japanese (JIS 0208-1990 and 0212-1990)", + 20936: "x-cp20936 - Simplified Chinese (GB2312); Chinese Simplified (GB2312-80)", + 20949: "x-cp20949 - Korean Wansung", + 21025: "cp1025 - IBM EBCDIC Cyrillic Serbian-Bulgarian", + 21027: "(deprecated)", + 21866: "koi8-u - Ukrainian (KOI8-U); Cyrillic (KOI8-U)", + 28591: "iso-8859-1 - ISO 8859-1 Latin 1; Western European (ISO)", + 28592: "iso-8859-2 - ISO 8859-2 Central European; Central European (ISO)", + 28593: "iso-8859-3 - ISO 8859-3 Latin 3", + 28594: "iso-8859-4 - ISO 8859-4 Baltic", + 28595: "iso-8859-5 - ISO 8859-5 Cyrillic", + 28596: "iso-8859-6 - ISO 8859-6 Arabic", + 28597: "iso-8859-7 - ISO 8859-7 Greek", + 28598: "iso-8859-8 - ISO 8859-8 Hebrew; Hebrew (ISO-Visual)", + 28599: "iso-8859-9 - ISO 8859-9 Turkish", + 28603: "iso-8859-13 - ISO 8859-13 Estonian", + 28605: "iso-8859-15 - ISO 8859-15 Latin 9", + 29001: "x-Europa - Europa 3", + 38598: "iso-8859-8-i - ISO 8859-8 Hebrew; Hebrew (ISO-Logical)", + 50220: "iso-2022-jp - ISO 2022 Japanese with no halfwidth Katakana; Japanese (JIS)", + 50221: "csISO2022JP - ISO 2022 Japanese with halfwidth Katakana; Japanese (JIS-Allow 1 byte Kana)", + 50222: "iso-2022-jp - ISO 2022 Japanese JIS X 0201-1989; Japanese (JIS-Allow 1 byte Kana - SO/SI)", + 50225: "iso-2022-kr - ISO 2022 Korean", + 50227: "x-cp50227 - ISO 2022 Simplified Chinese; Chinese Simplified (ISO 2022)", + 50229: "ISO 2022 - Traditional Chinese", + 50930: "EBCDIC - Japanese (Katakana) Extended", + 50931: "EBCDIC - US-Canada and Japanese", + 50933: "EBCDIC - Korean Extended and Korean", + 50935: "EBCDIC - Simplified Chinese Extended and Simplified Chinese", + 50936: "EBCDIC - Simplified Chinese", + 50937: "EBCDIC - US-Canada and Traditional Chinese", + 50939: "EBCDIC - Japanese (Latin) Extended and Japanese", + 51932: "euc-jp - EUC Japanese", + 51936: "EUC-CN - EUC Simplified Chinese; Chinese Simplified (EUC)", + 51949: "euc-kr - EUC Korean", + 51950: "EUC - Traditional Chinese", + 52936: "hz-gb-2312 - HZ-GB2312 Simplified Chinese; Chinese Simplified (HZ)", + 54936: "GB18030 - Windows XP and later: GB18030 Simplified Chinese (4 byte); Chinese Simplified (GB18030)", + 57002: "x-iscii-de - ISCII Devanagari", + 57003: "x-iscii-be - ISCII Bengali", + 57004: "x-iscii-ta - ISCII Tamil", + 57005: "x-iscii-te - ISCII Telugu", + 57006: "x-iscii-as - ISCII Assamese", + 57007: "x-iscii-or - ISCII Oriya", + 57008: "x-iscii-ka - ISCII Kannada", + 57009: "x-iscii-ma - ISCII Malayalam", + 57010: "x-iscii-gu - ISCII Gujarati", + 57011: "x-iscii-pa - ISCII Punjabi", + 65000: "utf-7 - Unicode (UTF-7)", + 65001: "utf-8 - Unicode (UTF-8)", +} diff --git a/vendor/github.com/richardlehane/msoleps/types/types.go b/vendor/github.com/richardlehane/msoleps/types/types.go new file mode 100644 index 00000000..75ea3828 --- /dev/null +++ b/vendor/github.com/richardlehane/msoleps/types/types.go @@ -0,0 +1,131 @@ +// Copyright 2014 Richard Lehane. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "encoding/binary" + "errors" +) + +// MakeVariant is defined in vectorArray.go. It calls Evaluate, which refers to the MakeTypes map, so must add at runtime +func init() { MakeTypes[VT_VARIANT] = MakeVariant } + +var ( + ErrType = errors.New("msoleps: error coercing byte stream to type") + ErrUnknownType = errors.New("msoleps: unknown type error") +) + +type Type interface { + String() string + Type() string + Length() int +} + +const ( + scalar uint16 = iota + vector + array +) + +func Evaluate(b []byte) (Type, error) { + if len(b) < 4 { + return I1(0), ErrType + } + id := TypeID(binary.LittleEndian.Uint16(b[:2])) + f, ok := MakeTypes[id] + if !ok { + return I1(0), ErrUnknownType + } + switch binary.LittleEndian.Uint16(b[2:4]) { + case vector: + return MakeVector(f, b[4:]) + case array: + return MakeArray(f, b[4:]) + case scalar: + if id != VT_VARIANT { // a VT_VARIANT can only be in a vector or array + return f(b[4:]) + } + } + return I1(0), ErrUnknownType + +} + +type TypeID uint16 + +const ( + VT_EMPTY TypeID = iota // 0x00 + VT_NULL + VT_I2 + VT_I4 + VT_R4 + VT_R8 + VT_CY + VT_DATE + VT_BSTR + _ + VT_ERROR + VT_BOOL + VT_VARIANT + _ + VT_DECIMAL + _ + VT_I1 + VT_U1 + VT_UI2 + VT_UI4 + VT_I8 + VT_UI8 + VT_INT + VT_UINT //0x17 + _ = iota + 5 + VT_LPSTR //0x1E + VT_LPWSTR + VT_FILETIME = iota + 0x25 // 0x40 + VT_BLOB + VT_STREAM + VT_STORAGE + VT_STREAMED_OBJECT + VT_STORED_OBJECT + VT_BLOB_OBJECT + VT_CF + VT_CLSID + VT_VERSIONED_STREAM // 0x49 +) + +type MakeType func([]byte) (Type, error) + +var MakeTypes map[TypeID]MakeType = map[TypeID]MakeType{ + VT_I2: MakeI2, + VT_I4: MakeI4, + VT_R4: MakeR4, + VT_R8: MakeR8, + VT_CY: MakeCurrency, + VT_DATE: MakeDate, + VT_BSTR: MakeCodeString, + VT_BOOL: MakeBool, + VT_DECIMAL: MakeDecimal, + VT_I1: MakeI1, + VT_U1: MakeUI1, + VT_UI2: MakeUI2, + VT_UI4: MakeUI4, + VT_I8: MakeI8, + VT_UI8: MakeUI8, + VT_INT: MakeI4, + VT_UINT: MakeUI4, + VT_LPSTR: MakeCodeString, + VT_LPWSTR: MakeUnicode, + VT_FILETIME: MakeFileTime, + VT_CLSID: MakeGuid, +} diff --git a/vendor/github.com/richardlehane/msoleps/types/vectorArray.go b/vendor/github.com/richardlehane/msoleps/types/vectorArray.go new file mode 100644 index 00000000..675f170d --- /dev/null +++ b/vendor/github.com/richardlehane/msoleps/types/vectorArray.go @@ -0,0 +1,115 @@ +// Copyright 2015 Richard Lehane. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import ( + "encoding/binary" +) + +type Vector []Type + +func (v Vector) String() string { + return "" +} + +func (v Vector) Type() string { + if len(v) > 0 { + return "Vector of " + v[0].Type() + } + return "Vector (empty)" +} + +func (v Vector) Length() int { + ret := 4 + for _, t := range v { + ret += t.Length() + } + return ret +} + +func MakeVector(f MakeType, b []byte) (Type, error) { + if len(b) < 4 { + return Vector{}, ErrType + } + l := int(binary.LittleEndian.Uint32(b[:4])) + v := make(Vector, l) + place := 4 + for i := 0; i < l; i++ { + t, err := f(b[place:]) + if err != nil { + return Vector{}, ErrType + } + v[i] = t + place += t.Length() + } + return v, nil +} + +type Array [][]Type + +func (a Array) String() string { + return "" +} + +func (a Array) Type() string { + if len(a) > 0 && len(a[0]) > 0 { + return "Array of " + a[0][0].Type() + } + return "Array (empty)" +} + +func (a Array) Length() int { + return 0 +} + +// TODO: Array not implemented yet +func MakeArray(f MakeType, b []byte) (Type, error) { + return Array{}, nil +} + +type Variant struct { + t Type +} + +func (v Variant) String() string { + return "Typed Property Value containing " + v.t.String() +} + +func (v Variant) Type() string { + return "Typed Property Value containing " + v.t.Type() +} + +func (v Variant) Length() int { + return 4 + v.t.Length() +} + +func MakeVariant(b []byte) (Type, error) { + if len(b) < 4 || binary.LittleEndian.Uint16(b[2:4]) != scalar { // only scalar values allowed + return Variant{}, ErrType + } + id := TypeID(binary.LittleEndian.Uint16(b[:2])) + if id == VT_VARIANT { + return Variant{}, ErrType // no recursive types allowed + } + f, ok := MakeTypes[id] + if !ok { + return Variant{}, ErrUnknownType + } + t, err := f(b[4:]) + if err != nil { + return Variant{}, err + } + return Variant{t}, nil +} diff --git a/vendor/github.com/rwcarlsen/goexif/LICENSE b/vendor/github.com/rwcarlsen/goexif/LICENSE new file mode 100644 index 00000000..aa625046 --- /dev/null +++ b/vendor/github.com/rwcarlsen/goexif/LICENSE @@ -0,0 +1,24 @@ + +Copyright (c) 2012, Robert Carlsen & Contributors +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/rwcarlsen/goexif/exif/README.md b/vendor/github.com/rwcarlsen/goexif/exif/README.md new file mode 100644 index 00000000..b3bf5fa0 --- /dev/null +++ b/vendor/github.com/rwcarlsen/goexif/exif/README.md @@ -0,0 +1,4 @@ + +To regenerate the regression test data, run `go generate` inside the exif +package directory and commit the changes to *regress_expected_test.go*. + diff --git a/vendor/github.com/rwcarlsen/goexif/exif/exif.go b/vendor/github.com/rwcarlsen/goexif/exif/exif.go new file mode 100644 index 00000000..03afe650 --- /dev/null +++ b/vendor/github.com/rwcarlsen/goexif/exif/exif.go @@ -0,0 +1,655 @@ +// Package exif implements decoding of EXIF data as defined in the EXIF 2.2 +// specification (http://www.exif.org/Exif2-2.PDF). +package exif + +import ( + "bufio" + "bytes" + "encoding/binary" + "encoding/json" + "errors" + "fmt" + "io" + "io/ioutil" + "math" + "strconv" + "strings" + "time" + + "github.com/rwcarlsen/goexif/tiff" +) + +const ( + jpeg_APP1 = 0xE1 + + exifPointer = 0x8769 + gpsPointer = 0x8825 + interopPointer = 0xA005 +) + +// A decodeError is returned when the image cannot be decoded as a tiff image. +type decodeError struct { + cause error +} + +func (de decodeError) Error() string { + return fmt.Sprintf("exif: decode failed (%v) ", de.cause.Error()) +} + +// IsShortReadTagValueError identifies a ErrShortReadTagValue error. +func IsShortReadTagValueError(err error) bool { + de, ok := err.(decodeError) + if ok { + return de.cause == tiff.ErrShortReadTagValue + } + return false +} + +// A TagNotPresentError is returned when the requested field is not +// present in the EXIF. +type TagNotPresentError FieldName + +func (tag TagNotPresentError) Error() string { + return fmt.Sprintf("exif: tag %q is not present", string(tag)) +} + +func IsTagNotPresentError(err error) bool { + _, ok := err.(TagNotPresentError) + return ok +} + +// Parser allows the registration of custom parsing and field loading +// in the Decode function. +type Parser interface { + // Parse should read data from x and insert parsed fields into x via + // LoadTags. + Parse(x *Exif) error +} + +var parsers []Parser + +func init() { + RegisterParsers(&parser{}) +} + +// RegisterParsers registers one or more parsers to be automatically called +// when decoding EXIF data via the Decode function. +func RegisterParsers(ps ...Parser) { + parsers = append(parsers, ps...) +} + +type parser struct{} + +type tiffErrors map[tiffError]string + +func (te tiffErrors) Error() string { + var allErrors []string + for k, v := range te { + allErrors = append(allErrors, fmt.Sprintf("%s: %v\n", stagePrefix[k], v)) + } + return strings.Join(allErrors, "\n") +} + +// IsCriticalError, given the error returned by Decode, reports whether the +// returned *Exif may contain usable information. +func IsCriticalError(err error) bool { + _, ok := err.(tiffErrors) + return !ok +} + +// IsExifError reports whether the error happened while decoding the EXIF +// sub-IFD. +func IsExifError(err error) bool { + if te, ok := err.(tiffErrors); ok { + _, isExif := te[loadExif] + return isExif + } + return false +} + +// IsGPSError reports whether the error happened while decoding the GPS sub-IFD. +func IsGPSError(err error) bool { + if te, ok := err.(tiffErrors); ok { + _, isGPS := te[loadExif] + return isGPS + } + return false +} + +// IsInteroperabilityError reports whether the error happened while decoding the +// Interoperability sub-IFD. +func IsInteroperabilityError(err error) bool { + if te, ok := err.(tiffErrors); ok { + _, isInterop := te[loadInteroperability] + return isInterop + } + return false +} + +type tiffError int + +const ( + loadExif tiffError = iota + loadGPS + loadInteroperability +) + +var stagePrefix = map[tiffError]string{ + loadExif: "loading EXIF sub-IFD", + loadGPS: "loading GPS sub-IFD", + loadInteroperability: "loading Interoperability sub-IFD", +} + +// Parse reads data from the tiff data in x and populates the tags +// in x. If parsing a sub-IFD fails, the error is recorded and +// parsing continues with the remaining sub-IFDs. +func (p *parser) Parse(x *Exif) error { + if len(x.Tiff.Dirs) == 0 { + return errors.New("Invalid exif data") + } + x.LoadTags(x.Tiff.Dirs[0], exifFields, false) + + // thumbnails + if len(x.Tiff.Dirs) >= 2 { + x.LoadTags(x.Tiff.Dirs[1], thumbnailFields, false) + } + + te := make(tiffErrors) + + // recurse into exif, gps, and interop sub-IFDs + if err := loadSubDir(x, ExifIFDPointer, exifFields); err != nil { + te[loadExif] = err.Error() + } + if err := loadSubDir(x, GPSInfoIFDPointer, gpsFields); err != nil { + te[loadGPS] = err.Error() + } + + if err := loadSubDir(x, InteroperabilityIFDPointer, interopFields); err != nil { + te[loadInteroperability] = err.Error() + } + if len(te) > 0 { + return te + } + return nil +} + +func loadSubDir(x *Exif, ptr FieldName, fieldMap map[uint16]FieldName) error { + r := bytes.NewReader(x.Raw) + + tag, err := x.Get(ptr) + if err != nil { + return nil + } + offset, err := tag.Int64(0) + if err != nil { + return nil + } + + _, err = r.Seek(offset, 0) + if err != nil { + return fmt.Errorf("exif: seek to sub-IFD %s failed: %v", ptr, err) + } + subDir, _, err := tiff.DecodeDir(r, x.Tiff.Order) + if err != nil { + return fmt.Errorf("exif: sub-IFD %s decode failed: %v", ptr, err) + } + x.LoadTags(subDir, fieldMap, false) + return nil +} + +// Exif provides access to decoded EXIF metadata fields and values. +type Exif struct { + Tiff *tiff.Tiff + main map[FieldName]*tiff.Tag + Raw []byte +} + +// Decode parses EXIF data from r (a TIFF, JPEG, or raw EXIF block) +// and returns a queryable Exif object. After the EXIF data section is +// called and the TIFF structure is decoded, each registered parser is +// called (in order of registration). If one parser returns an error, +// decoding terminates and the remaining parsers are not called. +// +// The error can be inspected with functions such as IsCriticalError +// to determine whether the returned object might still be usable. +func Decode(r io.Reader) (*Exif, error) { + + // EXIF data in JPEG is stored in the APP1 marker. EXIF data uses the TIFF + // format to store data. + // If we're parsing a TIFF image, we don't need to strip away any data. + // If we're parsing a JPEG image, we need to strip away the JPEG APP1 + // marker and also the EXIF header. + + header := make([]byte, 4) + n, err := io.ReadFull(r, header) + if err != nil { + return nil, fmt.Errorf("exif: error reading 4 byte header, got %d, %v", n, err) + } + + var isTiff bool + var isRawExif bool + var assumeJPEG bool + switch string(header) { + case "II*\x00": + // TIFF - Little endian (Intel) + isTiff = true + case "MM\x00*": + // TIFF - Big endian (Motorola) + isTiff = true + case "Exif": + isRawExif = true + default: + // Not TIFF, assume JPEG + assumeJPEG = true + } + + // Put the header bytes back into the reader. + r = io.MultiReader(bytes.NewReader(header), r) + var ( + er *bytes.Reader + tif *tiff.Tiff + sec *appSec + ) + + switch { + case isRawExif: + var header [6]byte + if _, err := io.ReadFull(r, header[:]); err != nil { + return nil, fmt.Errorf("exif: unexpected raw exif header read error") + } + if got, want := string(header[:]), "Exif\x00\x00"; got != want { + return nil, fmt.Errorf("exif: unexpected raw exif header; got %q, want %q", got, want) + } + fallthrough + case isTiff: + // Functions below need the IFDs from the TIFF data to be stored in a + // *bytes.Reader. We use TeeReader to get a copy of the bytes as a + // side-effect of tiff.Decode() doing its work. + b := &bytes.Buffer{} + tr := io.TeeReader(r, b) + tif, err = tiff.Decode(tr) + er = bytes.NewReader(b.Bytes()) + case assumeJPEG: + // Locate the JPEG APP1 header. + sec, err = newAppSec(jpeg_APP1, r) + if err != nil { + return nil, err + } + // Strip away EXIF header. + er, err = sec.exifReader() + if err != nil { + return nil, err + } + tif, err = tiff.Decode(er) + } + + if err != nil { + return nil, decodeError{cause: err} + } + + er.Seek(0, 0) + raw, err := ioutil.ReadAll(er) + if err != nil { + return nil, decodeError{cause: err} + } + + // build an exif structure from the tiff + x := &Exif{ + main: map[FieldName]*tiff.Tag{}, + Tiff: tif, + Raw: raw, + } + + for i, p := range parsers { + if err := p.Parse(x); err != nil { + if _, ok := err.(tiffErrors); ok { + return x, err + } + // This should never happen, as Parse always returns a tiffError + // for now, but that could change. + return x, fmt.Errorf("exif: parser %v failed (%v)", i, err) + } + } + + return x, nil +} + +// LoadTags loads tags into the available fields from the tiff Directory +// using the given tagid-fieldname mapping. Used to load makernote and +// other meta-data. If showMissing is true, tags in d that are not in the +// fieldMap will be loaded with the FieldName UnknownPrefix followed by the +// tag ID (in hex format). +func (x *Exif) LoadTags(d *tiff.Dir, fieldMap map[uint16]FieldName, showMissing bool) { + for _, tag := range d.Tags { + name := fieldMap[tag.Id] + if name == "" { + if !showMissing { + continue + } + name = FieldName(fmt.Sprintf("%v%x", UnknownPrefix, tag.Id)) + } + x.main[name] = tag + } +} + +// Get retrieves the EXIF tag for the given field name. +// +// If the tag is not known or not present, an error is returned. If the +// tag name is known, the error will be a TagNotPresentError. +func (x *Exif) Get(name FieldName) (*tiff.Tag, error) { + if tg, ok := x.main[name]; ok { + return tg, nil + } + return nil, TagNotPresentError(name) +} + +// Walker is the interface used to traverse all fields of an Exif object. +type Walker interface { + // Walk is called for each non-nil EXIF field. Returning a non-nil + // error aborts the walk/traversal. + Walk(name FieldName, tag *tiff.Tag) error +} + +// Walk calls the Walk method of w with the name and tag for every non-nil +// EXIF field. If w aborts the walk with an error, that error is returned. +func (x *Exif) Walk(w Walker) error { + for name, tag := range x.main { + if err := w.Walk(name, tag); err != nil { + return err + } + } + return nil +} + +// DateTime returns the EXIF's "DateTimeOriginal" field, which +// is the creation time of the photo. If not found, it tries +// the "DateTime" (which is meant as the modtime) instead. +// The error will be TagNotPresentErr if none of those tags +// were found, or a generic error if the tag value was +// not a string, or the error returned by time.Parse. +// +// If the EXIF lacks timezone information or GPS time, the returned +// time's Location will be time.Local. +func (x *Exif) DateTime() (time.Time, error) { + var dt time.Time + tag, err := x.Get(DateTimeOriginal) + if err != nil { + tag, err = x.Get(DateTime) + if err != nil { + return dt, err + } + } + if tag.Format() != tiff.StringVal { + return dt, errors.New("DateTime[Original] not in string format") + } + exifTimeLayout := "2006:01:02 15:04:05" + dateStr := strings.TrimRight(string(tag.Val), "\x00") + // TODO(bradfitz,mpl): look for timezone offset, GPS time, etc. + timeZone := time.Local + if tz, _ := x.TimeZone(); tz != nil { + timeZone = tz + } + return time.ParseInLocation(exifTimeLayout, dateStr, timeZone) +} + +func (x *Exif) TimeZone() (*time.Location, error) { + // TODO: parse more timezone fields (e.g. Nikon WorldTime). + timeInfo, err := x.Get("Canon.TimeInfo") + if err != nil { + return nil, err + } + if timeInfo.Count < 2 { + return nil, errors.New("Canon.TimeInfo does not contain timezone") + } + offsetMinutes, err := timeInfo.Int(1) + if err != nil { + return nil, err + } + return time.FixedZone("", offsetMinutes*60), nil +} + +func ratFloat(num, dem int64) float64 { + return float64(num) / float64(dem) +} + +// Tries to parse a Geo degrees value from a string as it was found in some +// EXIF data. +// Supported formats so far: +// - "52,00000,50,00000,34,01180" ==> 52 deg 50'34.0118" +// Probably due to locale the comma is used as decimal mark as well as the +// separator of three floats (degrees, minutes, seconds) +// http://en.wikipedia.org/wiki/Decimal_mark#Hindu.E2.80.93Arabic_numeral_system +// - "52.0,50.0,34.01180" ==> 52deg50'34.0118" +// - "52,50,34.01180" ==> 52deg50'34.0118" +func parseTagDegreesString(s string) (float64, error) { + const unparsableErrorFmt = "Unknown coordinate format: %s" + isSplitRune := func(c rune) bool { + return c == ',' || c == ';' + } + parts := strings.FieldsFunc(s, isSplitRune) + var degrees, minutes, seconds float64 + var err error + switch len(parts) { + case 6: + degrees, err = strconv.ParseFloat(parts[0]+"."+parts[1], 64) + if err != nil { + return 0.0, fmt.Errorf(unparsableErrorFmt, s) + } + minutes, err = strconv.ParseFloat(parts[2]+"."+parts[3], 64) + if err != nil { + return 0.0, fmt.Errorf(unparsableErrorFmt, s) + } + minutes = math.Copysign(minutes, degrees) + seconds, err = strconv.ParseFloat(parts[4]+"."+parts[5], 64) + if err != nil { + return 0.0, fmt.Errorf(unparsableErrorFmt, s) + } + seconds = math.Copysign(seconds, degrees) + case 3: + degrees, err = strconv.ParseFloat(parts[0], 64) + if err != nil { + return 0.0, fmt.Errorf(unparsableErrorFmt, s) + } + minutes, err = strconv.ParseFloat(parts[1], 64) + if err != nil { + return 0.0, fmt.Errorf(unparsableErrorFmt, s) + } + minutes = math.Copysign(minutes, degrees) + seconds, err = strconv.ParseFloat(parts[2], 64) + if err != nil { + return 0.0, fmt.Errorf(unparsableErrorFmt, s) + } + seconds = math.Copysign(seconds, degrees) + default: + return 0.0, fmt.Errorf(unparsableErrorFmt, s) + } + return degrees + minutes/60.0 + seconds/3600.0, nil +} + +func parse3Rat2(tag *tiff.Tag) ([3]float64, error) { + v := [3]float64{} + for i := range v { + num, den, err := tag.Rat2(i) + if err != nil { + return v, err + } + v[i] = ratFloat(num, den) + if tag.Count < uint32(i+2) { + break + } + } + return v, nil +} + +func tagDegrees(tag *tiff.Tag) (float64, error) { + switch tag.Format() { + case tiff.RatVal: + // The usual case, according to the Exif spec + // (http://www.kodak.com/global/plugins/acrobat/en/service/digCam/exifStandard2.pdf, + // sec 4.6.6, p. 52 et seq.) + v, err := parse3Rat2(tag) + if err != nil { + return 0.0, err + } + return v[0] + v[1]/60 + v[2]/3600.0, nil + case tiff.StringVal: + // Encountered this weird case with a panorama picture taken with a HTC phone + s, err := tag.StringVal() + if err != nil { + return 0.0, err + } + return parseTagDegreesString(s) + default: + // don't know how to parse value, give up + return 0.0, fmt.Errorf("Malformed EXIF Tag Degrees") + } +} + +// LatLong returns the latitude and longitude of the photo and +// whether it was present. +func (x *Exif) LatLong() (lat, long float64, err error) { + // All calls of x.Get might return an TagNotPresentError + longTag, err := x.Get(FieldName("GPSLongitude")) + if err != nil { + return + } + ewTag, err := x.Get(FieldName("GPSLongitudeRef")) + if err != nil { + return + } + latTag, err := x.Get(FieldName("GPSLatitude")) + if err != nil { + return + } + nsTag, err := x.Get(FieldName("GPSLatitudeRef")) + if err != nil { + return + } + if long, err = tagDegrees(longTag); err != nil { + return 0, 0, fmt.Errorf("Cannot parse longitude: %v", err) + } + if lat, err = tagDegrees(latTag); err != nil { + return 0, 0, fmt.Errorf("Cannot parse latitude: %v", err) + } + ew, err := ewTag.StringVal() + if err == nil && ew == "W" { + long *= -1.0 + } else if err != nil { + return 0, 0, fmt.Errorf("Cannot parse longitude: %v", err) + } + ns, err := nsTag.StringVal() + if err == nil && ns == "S" { + lat *= -1.0 + } else if err != nil { + return 0, 0, fmt.Errorf("Cannot parse longitude: %v", err) + } + return lat, long, nil +} + +// String returns a pretty text representation of the decoded exif data. +func (x *Exif) String() string { + var buf bytes.Buffer + for name, tag := range x.main { + fmt.Fprintf(&buf, "%s: %s\n", name, tag) + } + return buf.String() +} + +// JpegThumbnail returns the jpeg thumbnail if it exists. If it doesn't exist, +// TagNotPresentError will be returned +func (x *Exif) JpegThumbnail() ([]byte, error) { + offset, err := x.Get(ThumbJPEGInterchangeFormat) + if err != nil { + return nil, err + } + start, err := offset.Int(0) + if err != nil { + return nil, err + } + + length, err := x.Get(ThumbJPEGInterchangeFormatLength) + if err != nil { + return nil, err + } + l, err := length.Int(0) + if err != nil { + return nil, err + } + + return x.Raw[start : start+l], nil +} + +// MarshalJson implements the encoding/json.Marshaler interface providing output of +// all EXIF fields present (names and values). +func (x Exif) MarshalJSON() ([]byte, error) { + return json.Marshal(x.main) +} + +type appSec struct { + marker byte + data []byte +} + +// newAppSec finds marker in r and returns the corresponding application data +// section. +func newAppSec(marker byte, r io.Reader) (*appSec, error) { + br := bufio.NewReader(r) + app := &appSec{marker: marker} + var dataLen int + + // seek to marker + for dataLen == 0 { + if _, err := br.ReadBytes(0xFF); err != nil { + return nil, err + } + c, err := br.ReadByte() + if err != nil { + return nil, err + } else if c != marker { + continue + } + + dataLenBytes := make([]byte, 2) + for k, _ := range dataLenBytes { + c, err := br.ReadByte() + if err != nil { + return nil, err + } + dataLenBytes[k] = c + } + dataLen = int(binary.BigEndian.Uint16(dataLenBytes)) - 2 + } + + // read section data + nread := 0 + for nread < dataLen { + s := make([]byte, dataLen-nread) + n, err := br.Read(s) + nread += n + if err != nil && nread < dataLen { + return nil, err + } + app.data = append(app.data, s[:n]...) + } + return app, nil +} + +// reader returns a reader on this appSec. +func (app *appSec) reader() *bytes.Reader { + return bytes.NewReader(app.data) +} + +// exifReader returns a reader on this appSec with the read cursor advanced to +// the start of the exif's tiff encoded portion. +func (app *appSec) exifReader() (*bytes.Reader, error) { + if len(app.data) < 6 { + return nil, errors.New("exif: failed to find exif intro marker") + } + + // read/check for exif special mark + exif := app.data[:6] + if !bytes.Equal(exif, append([]byte("Exif"), 0x00, 0x00)) { + return nil, errors.New("exif: failed to find exif intro marker") + } + return bytes.NewReader(app.data[6:]), nil +} diff --git a/vendor/github.com/rwcarlsen/goexif/exif/fields.go b/vendor/github.com/rwcarlsen/goexif/exif/fields.go new file mode 100644 index 00000000..8b8ae0f2 --- /dev/null +++ b/vendor/github.com/rwcarlsen/goexif/exif/fields.go @@ -0,0 +1,309 @@ +package exif + +type FieldName string + +// UnknownPrefix is used as the first part of field names for decoded tags for +// which there is no known/supported EXIF field. +const UnknownPrefix = "UnknownTag_" + +// Primary EXIF fields +const ( + ImageWidth FieldName = "ImageWidth" + ImageLength FieldName = "ImageLength" // Image height called Length by EXIF spec + BitsPerSample FieldName = "BitsPerSample" + Compression FieldName = "Compression" + PhotometricInterpretation FieldName = "PhotometricInterpretation" + Orientation FieldName = "Orientation" + SamplesPerPixel FieldName = "SamplesPerPixel" + PlanarConfiguration FieldName = "PlanarConfiguration" + YCbCrSubSampling FieldName = "YCbCrSubSampling" + YCbCrPositioning FieldName = "YCbCrPositioning" + XResolution FieldName = "XResolution" + YResolution FieldName = "YResolution" + ResolutionUnit FieldName = "ResolutionUnit" + DateTime FieldName = "DateTime" + ImageDescription FieldName = "ImageDescription" + Make FieldName = "Make" + Model FieldName = "Model" + Software FieldName = "Software" + Artist FieldName = "Artist" + Copyright FieldName = "Copyright" + ExifIFDPointer FieldName = "ExifIFDPointer" + GPSInfoIFDPointer FieldName = "GPSInfoIFDPointer" + InteroperabilityIFDPointer FieldName = "InteroperabilityIFDPointer" + ExifVersion FieldName = "ExifVersion" + FlashpixVersion FieldName = "FlashpixVersion" + ColorSpace FieldName = "ColorSpace" + ComponentsConfiguration FieldName = "ComponentsConfiguration" + CompressedBitsPerPixel FieldName = "CompressedBitsPerPixel" + PixelXDimension FieldName = "PixelXDimension" + PixelYDimension FieldName = "PixelYDimension" + MakerNote FieldName = "MakerNote" + UserComment FieldName = "UserComment" + RelatedSoundFile FieldName = "RelatedSoundFile" + DateTimeOriginal FieldName = "DateTimeOriginal" + DateTimeDigitized FieldName = "DateTimeDigitized" + SubSecTime FieldName = "SubSecTime" + SubSecTimeOriginal FieldName = "SubSecTimeOriginal" + SubSecTimeDigitized FieldName = "SubSecTimeDigitized" + ImageUniqueID FieldName = "ImageUniqueID" + ExposureTime FieldName = "ExposureTime" + FNumber FieldName = "FNumber" + ExposureProgram FieldName = "ExposureProgram" + SpectralSensitivity FieldName = "SpectralSensitivity" + ISOSpeedRatings FieldName = "ISOSpeedRatings" + OECF FieldName = "OECF" + ShutterSpeedValue FieldName = "ShutterSpeedValue" + ApertureValue FieldName = "ApertureValue" + BrightnessValue FieldName = "BrightnessValue" + ExposureBiasValue FieldName = "ExposureBiasValue" + MaxApertureValue FieldName = "MaxApertureValue" + SubjectDistance FieldName = "SubjectDistance" + MeteringMode FieldName = "MeteringMode" + LightSource FieldName = "LightSource" + Flash FieldName = "Flash" + FocalLength FieldName = "FocalLength" + SubjectArea FieldName = "SubjectArea" + FlashEnergy FieldName = "FlashEnergy" + SpatialFrequencyResponse FieldName = "SpatialFrequencyResponse" + FocalPlaneXResolution FieldName = "FocalPlaneXResolution" + FocalPlaneYResolution FieldName = "FocalPlaneYResolution" + FocalPlaneResolutionUnit FieldName = "FocalPlaneResolutionUnit" + SubjectLocation FieldName = "SubjectLocation" + ExposureIndex FieldName = "ExposureIndex" + SensingMethod FieldName = "SensingMethod" + FileSource FieldName = "FileSource" + SceneType FieldName = "SceneType" + CFAPattern FieldName = "CFAPattern" + CustomRendered FieldName = "CustomRendered" + ExposureMode FieldName = "ExposureMode" + WhiteBalance FieldName = "WhiteBalance" + DigitalZoomRatio FieldName = "DigitalZoomRatio" + FocalLengthIn35mmFilm FieldName = "FocalLengthIn35mmFilm" + SceneCaptureType FieldName = "SceneCaptureType" + GainControl FieldName = "GainControl" + Contrast FieldName = "Contrast" + Saturation FieldName = "Saturation" + Sharpness FieldName = "Sharpness" + DeviceSettingDescription FieldName = "DeviceSettingDescription" + SubjectDistanceRange FieldName = "SubjectDistanceRange" + LensMake FieldName = "LensMake" + LensModel FieldName = "LensModel" +) + +// Windows-specific tags +const ( + XPTitle FieldName = "XPTitle" + XPComment FieldName = "XPComment" + XPAuthor FieldName = "XPAuthor" + XPKeywords FieldName = "XPKeywords" + XPSubject FieldName = "XPSubject" +) + +// thumbnail fields +const ( + ThumbJPEGInterchangeFormat FieldName = "ThumbJPEGInterchangeFormat" // offset to thumb jpeg SOI + ThumbJPEGInterchangeFormatLength FieldName = "ThumbJPEGInterchangeFormatLength" // byte length of thumb +) + +// GPS fields +const ( + GPSVersionID FieldName = "GPSVersionID" + GPSLatitudeRef FieldName = "GPSLatitudeRef" + GPSLatitude FieldName = "GPSLatitude" + GPSLongitudeRef FieldName = "GPSLongitudeRef" + GPSLongitude FieldName = "GPSLongitude" + GPSAltitudeRef FieldName = "GPSAltitudeRef" + GPSAltitude FieldName = "GPSAltitude" + GPSTimeStamp FieldName = "GPSTimeStamp" + GPSSatelites FieldName = "GPSSatelites" + GPSStatus FieldName = "GPSStatus" + GPSMeasureMode FieldName = "GPSMeasureMode" + GPSDOP FieldName = "GPSDOP" + GPSSpeedRef FieldName = "GPSSpeedRef" + GPSSpeed FieldName = "GPSSpeed" + GPSTrackRef FieldName = "GPSTrackRef" + GPSTrack FieldName = "GPSTrack" + GPSImgDirectionRef FieldName = "GPSImgDirectionRef" + GPSImgDirection FieldName = "GPSImgDirection" + GPSMapDatum FieldName = "GPSMapDatum" + GPSDestLatitudeRef FieldName = "GPSDestLatitudeRef" + GPSDestLatitude FieldName = "GPSDestLatitude" + GPSDestLongitudeRef FieldName = "GPSDestLongitudeRef" + GPSDestLongitude FieldName = "GPSDestLongitude" + GPSDestBearingRef FieldName = "GPSDestBearingRef" + GPSDestBearing FieldName = "GPSDestBearing" + GPSDestDistanceRef FieldName = "GPSDestDistanceRef" + GPSDestDistance FieldName = "GPSDestDistance" + GPSProcessingMethod FieldName = "GPSProcessingMethod" + GPSAreaInformation FieldName = "GPSAreaInformation" + GPSDateStamp FieldName = "GPSDateStamp" + GPSDifferential FieldName = "GPSDifferential" +) + +// interoperability fields +const ( + InteroperabilityIndex FieldName = "InteroperabilityIndex" +) + +var exifFields = map[uint16]FieldName{ + ///////////////////////////////////// + ////////// IFD 0 //////////////////// + ///////////////////////////////////// + + // image data structure for the thumbnail + 0x0100: ImageWidth, + 0x0101: ImageLength, + 0x0102: BitsPerSample, + 0x0103: Compression, + 0x0106: PhotometricInterpretation, + 0x0112: Orientation, + 0x0115: SamplesPerPixel, + 0x011C: PlanarConfiguration, + 0x0212: YCbCrSubSampling, + 0x0213: YCbCrPositioning, + 0x011A: XResolution, + 0x011B: YResolution, + 0x0128: ResolutionUnit, + + // Other tags + 0x0132: DateTime, + 0x010E: ImageDescription, + 0x010F: Make, + 0x0110: Model, + 0x0131: Software, + 0x013B: Artist, + 0x8298: Copyright, + + // Windows-specific tags + 0x9c9b: XPTitle, + 0x9c9c: XPComment, + 0x9c9d: XPAuthor, + 0x9c9e: XPKeywords, + 0x9c9f: XPSubject, + + // private tags + exifPointer: ExifIFDPointer, + + ///////////////////////////////////// + ////////// Exif sub IFD ///////////// + ///////////////////////////////////// + + gpsPointer: GPSInfoIFDPointer, + interopPointer: InteroperabilityIFDPointer, + + 0x9000: ExifVersion, + 0xA000: FlashpixVersion, + + 0xA001: ColorSpace, + + 0x9101: ComponentsConfiguration, + 0x9102: CompressedBitsPerPixel, + 0xA002: PixelXDimension, + 0xA003: PixelYDimension, + + 0x927C: MakerNote, + 0x9286: UserComment, + + 0xA004: RelatedSoundFile, + 0x9003: DateTimeOriginal, + 0x9004: DateTimeDigitized, + 0x9290: SubSecTime, + 0x9291: SubSecTimeOriginal, + 0x9292: SubSecTimeDigitized, + + 0xA420: ImageUniqueID, + + // picture conditions + 0x829A: ExposureTime, + 0x829D: FNumber, + 0x8822: ExposureProgram, + 0x8824: SpectralSensitivity, + 0x8827: ISOSpeedRatings, + 0x8828: OECF, + 0x9201: ShutterSpeedValue, + 0x9202: ApertureValue, + 0x9203: BrightnessValue, + 0x9204: ExposureBiasValue, + 0x9205: MaxApertureValue, + 0x9206: SubjectDistance, + 0x9207: MeteringMode, + 0x9208: LightSource, + 0x9209: Flash, + 0x920A: FocalLength, + 0x9214: SubjectArea, + 0xA20B: FlashEnergy, + 0xA20C: SpatialFrequencyResponse, + 0xA20E: FocalPlaneXResolution, + 0xA20F: FocalPlaneYResolution, + 0xA210: FocalPlaneResolutionUnit, + 0xA214: SubjectLocation, + 0xA215: ExposureIndex, + 0xA217: SensingMethod, + 0xA300: FileSource, + 0xA301: SceneType, + 0xA302: CFAPattern, + 0xA401: CustomRendered, + 0xA402: ExposureMode, + 0xA403: WhiteBalance, + 0xA404: DigitalZoomRatio, + 0xA405: FocalLengthIn35mmFilm, + 0xA406: SceneCaptureType, + 0xA407: GainControl, + 0xA408: Contrast, + 0xA409: Saturation, + 0xA40A: Sharpness, + 0xA40B: DeviceSettingDescription, + 0xA40C: SubjectDistanceRange, + 0xA433: LensMake, + 0xA434: LensModel, +} + +var gpsFields = map[uint16]FieldName{ + ///////////////////////////////////// + //// GPS sub-IFD //////////////////// + ///////////////////////////////////// + 0x0: GPSVersionID, + 0x1: GPSLatitudeRef, + 0x2: GPSLatitude, + 0x3: GPSLongitudeRef, + 0x4: GPSLongitude, + 0x5: GPSAltitudeRef, + 0x6: GPSAltitude, + 0x7: GPSTimeStamp, + 0x8: GPSSatelites, + 0x9: GPSStatus, + 0xA: GPSMeasureMode, + 0xB: GPSDOP, + 0xC: GPSSpeedRef, + 0xD: GPSSpeed, + 0xE: GPSTrackRef, + 0xF: GPSTrack, + 0x10: GPSImgDirectionRef, + 0x11: GPSImgDirection, + 0x12: GPSMapDatum, + 0x13: GPSDestLatitudeRef, + 0x14: GPSDestLatitude, + 0x15: GPSDestLongitudeRef, + 0x16: GPSDestLongitude, + 0x17: GPSDestBearingRef, + 0x18: GPSDestBearing, + 0x19: GPSDestDistanceRef, + 0x1A: GPSDestDistance, + 0x1B: GPSProcessingMethod, + 0x1C: GPSAreaInformation, + 0x1D: GPSDateStamp, + 0x1E: GPSDifferential, +} + +var interopFields = map[uint16]FieldName{ + ///////////////////////////////////// + //// Interoperability sub-IFD /////// + ///////////////////////////////////// + 0x1: InteroperabilityIndex, +} + +var thumbnailFields = map[uint16]FieldName{ + 0x0201: ThumbJPEGInterchangeFormat, + 0x0202: ThumbJPEGInterchangeFormatLength, +} diff --git a/vendor/github.com/rwcarlsen/goexif/exif/sample1.jpg b/vendor/github.com/rwcarlsen/goexif/exif/sample1.jpg new file mode 100644 index 00000000..87bcf8e3 Binary files /dev/null and b/vendor/github.com/rwcarlsen/goexif/exif/sample1.jpg differ diff --git a/vendor/github.com/rwcarlsen/goexif/tiff/sample1.tif b/vendor/github.com/rwcarlsen/goexif/tiff/sample1.tif new file mode 100644 index 00000000..d7c19f25 Binary files /dev/null and b/vendor/github.com/rwcarlsen/goexif/tiff/sample1.tif differ diff --git a/vendor/github.com/rwcarlsen/goexif/tiff/tag.go b/vendor/github.com/rwcarlsen/goexif/tiff/tag.go new file mode 100644 index 00000000..b9ce791f --- /dev/null +++ b/vendor/github.com/rwcarlsen/goexif/tiff/tag.go @@ -0,0 +1,445 @@ +package tiff + +import ( + "bytes" + "encoding/binary" + "errors" + "fmt" + "io" + "math/big" + "strings" + "unicode" + "unicode/utf8" +) + +// Format specifies the Go type equivalent used to represent the basic +// tiff data types. +type Format int + +const ( + IntVal Format = iota + FloatVal + RatVal + StringVal + UndefVal + OtherVal +) + +var ErrShortReadTagValue = errors.New("tiff: short read of tag value") + +var formatNames = map[Format]string{ + IntVal: "int", + FloatVal: "float", + RatVal: "rational", + StringVal: "string", + UndefVal: "undefined", + OtherVal: "other", +} + +// DataType represents the basic tiff tag data types. +type DataType uint16 + +const ( + DTByte DataType = 1 + DTAscii DataType = 2 + DTShort DataType = 3 + DTLong DataType = 4 + DTRational DataType = 5 + DTSByte DataType = 6 + DTUndefined DataType = 7 + DTSShort DataType = 8 + DTSLong DataType = 9 + DTSRational DataType = 10 + DTFloat DataType = 11 + DTDouble DataType = 12 +) + +var typeNames = map[DataType]string{ + DTByte: "byte", + DTAscii: "ascii", + DTShort: "short", + DTLong: "long", + DTRational: "rational", + DTSByte: "signed byte", + DTUndefined: "undefined", + DTSShort: "signed short", + DTSLong: "signed long", + DTSRational: "signed rational", + DTFloat: "float", + DTDouble: "double", +} + +// typeSize specifies the size in bytes of each type. +var typeSize = map[DataType]uint32{ + DTByte: 1, + DTAscii: 1, + DTShort: 2, + DTLong: 4, + DTRational: 8, + DTSByte: 1, + DTUndefined: 1, + DTSShort: 2, + DTSLong: 4, + DTSRational: 8, + DTFloat: 4, + DTDouble: 8, +} + +// Tag reflects the parsed content of a tiff IFD tag. +type Tag struct { + // Id is the 2-byte tiff tag identifier. + Id uint16 + // Type is an integer (1 through 12) indicating the tag value's data type. + Type DataType + // Count is the number of type Type stored in the tag's value (i.e. the + // tag's value is an array of type Type and length Count). + Count uint32 + // Val holds the bytes that represent the tag's value. + Val []byte + // ValOffset holds byte offset of the tag value w.r.t. the beginning of the + // reader it was decoded from. Zero if the tag value fit inside the offset + // field. + ValOffset uint32 + + order binary.ByteOrder + intVals []int64 + floatVals []float64 + ratVals [][]int64 + strVal string + format Format +} + +// DecodeTag parses a tiff-encoded IFD tag from r and returns a Tag object. The +// first read from r should be the first byte of the tag. ReadAt offsets should +// generally be relative to the beginning of the tiff structure (not relative +// to the beginning of the tag). +func DecodeTag(r ReadAtReader, order binary.ByteOrder) (*Tag, error) { + t := new(Tag) + t.order = order + + err := binary.Read(r, order, &t.Id) + if err != nil { + return nil, errors.New("tiff: tag id read failed: " + err.Error()) + } + + err = binary.Read(r, order, &t.Type) + if err != nil { + return nil, errors.New("tiff: tag type read failed: " + err.Error()) + } + + err = binary.Read(r, order, &t.Count) + if err != nil { + return nil, errors.New("tiff: tag component count read failed: " + err.Error()) + } + + // There seems to be a relatively common corrupt tag which has a Count of + // MaxUint32. This is probably not a valid value, so return early. + if t.Count == 1<<32-1 { + return t, errors.New("invalid Count offset in tag") + } + + valLen := typeSize[t.Type] * t.Count + if valLen == 0 { + return t, errors.New("zero length tag value") + } + + if valLen > 4 { + binary.Read(r, order, &t.ValOffset) + + // Use a bytes.Buffer so we don't allocate a huge slice if the tag + // is corrupt. + var buff bytes.Buffer + sr := io.NewSectionReader(r, int64(t.ValOffset), int64(valLen)) + n, err := io.Copy(&buff, sr) + if err != nil { + return t, errors.New("tiff: tag value read failed: " + err.Error()) + } else if n != int64(valLen) { + return t, ErrShortReadTagValue + } + t.Val = buff.Bytes() + + } else { + val := make([]byte, valLen) + if _, err = io.ReadFull(r, val); err != nil { + return t, errors.New("tiff: tag offset read failed: " + err.Error()) + } + // ignore padding. + if _, err = io.ReadFull(r, make([]byte, 4-valLen)); err != nil { + return t, errors.New("tiff: tag offset read failed: " + err.Error()) + } + + t.Val = val + } + + return t, t.convertVals() +} + +func (t *Tag) convertVals() error { + r := bytes.NewReader(t.Val) + + switch t.Type { + case DTAscii: + if len(t.Val) <= 0 { + break + } + nullPos := bytes.IndexByte(t.Val, 0) + if nullPos == -1 { + t.strVal = string(t.Val) + } else { + // ignore all trailing NULL bytes, in case of a broken t.Count + t.strVal = string(t.Val[:nullPos]) + } + case DTByte: + var v uint8 + t.intVals = make([]int64, int(t.Count)) + for i := range t.intVals { + err := binary.Read(r, t.order, &v) + if err != nil { + return err + } + t.intVals[i] = int64(v) + } + case DTShort: + var v uint16 + t.intVals = make([]int64, int(t.Count)) + for i := range t.intVals { + err := binary.Read(r, t.order, &v) + if err != nil { + return err + } + t.intVals[i] = int64(v) + } + case DTLong: + var v uint32 + t.intVals = make([]int64, int(t.Count)) + for i := range t.intVals { + err := binary.Read(r, t.order, &v) + if err != nil { + return err + } + t.intVals[i] = int64(v) + } + case DTSByte: + var v int8 + t.intVals = make([]int64, int(t.Count)) + for i := range t.intVals { + err := binary.Read(r, t.order, &v) + if err != nil { + return err + } + t.intVals[i] = int64(v) + } + case DTSShort: + var v int16 + t.intVals = make([]int64, int(t.Count)) + for i := range t.intVals { + err := binary.Read(r, t.order, &v) + if err != nil { + return err + } + t.intVals[i] = int64(v) + } + case DTSLong: + var v int32 + t.intVals = make([]int64, int(t.Count)) + for i := range t.intVals { + err := binary.Read(r, t.order, &v) + if err != nil { + return err + } + t.intVals[i] = int64(v) + } + case DTRational: + t.ratVals = make([][]int64, int(t.Count)) + for i := range t.ratVals { + var n, d uint32 + err := binary.Read(r, t.order, &n) + if err != nil { + return err + } + err = binary.Read(r, t.order, &d) + if err != nil { + return err + } + t.ratVals[i] = []int64{int64(n), int64(d)} + } + case DTSRational: + t.ratVals = make([][]int64, int(t.Count)) + for i := range t.ratVals { + var n, d int32 + err := binary.Read(r, t.order, &n) + if err != nil { + return err + } + err = binary.Read(r, t.order, &d) + if err != nil { + return err + } + t.ratVals[i] = []int64{int64(n), int64(d)} + } + case DTFloat: // float32 + t.floatVals = make([]float64, int(t.Count)) + for i := range t.floatVals { + var v float32 + err := binary.Read(r, t.order, &v) + if err != nil { + return err + } + t.floatVals[i] = float64(v) + } + case DTDouble: + t.floatVals = make([]float64, int(t.Count)) + for i := range t.floatVals { + var u float64 + err := binary.Read(r, t.order, &u) + if err != nil { + return err + } + t.floatVals[i] = u + } + } + + switch t.Type { + case DTByte, DTShort, DTLong, DTSByte, DTSShort, DTSLong: + t.format = IntVal + case DTRational, DTSRational: + t.format = RatVal + case DTFloat, DTDouble: + t.format = FloatVal + case DTAscii: + t.format = StringVal + case DTUndefined: + t.format = UndefVal + default: + t.format = OtherVal + } + + return nil +} + +// Format returns a value indicating which method can be called to retrieve the +// tag's value properly typed (e.g. integer, rational, etc.). +func (t *Tag) Format() Format { return t.format } + +func (t *Tag) typeErr(to Format) error { + return &wrongFmtErr{typeNames[t.Type], formatNames[to]} +} + +// Rat returns the tag's i'th value as a rational number. It returns a nil and +// an error if this tag's Format is not RatVal. It panics for zero deminators +// or if i is out of range. +func (t *Tag) Rat(i int) (*big.Rat, error) { + n, d, err := t.Rat2(i) + if err != nil { + return nil, err + } + return big.NewRat(n, d), nil +} + +// Rat2 returns the tag's i'th value as a rational number represented by a +// numerator-denominator pair. It returns an error if the tag's Format is not +// RatVal. It panics if i is out of range. +func (t *Tag) Rat2(i int) (num, den int64, err error) { + if t.format != RatVal { + return 0, 0, t.typeErr(RatVal) + } + return t.ratVals[i][0], t.ratVals[i][1], nil +} + +// Int64 returns the tag's i'th value as an integer. It returns an error if the +// tag's Format is not IntVal. It panics if i is out of range. +func (t *Tag) Int64(i int) (int64, error) { + if t.format != IntVal { + return 0, t.typeErr(IntVal) + } + return t.intVals[i], nil +} + +// Int returns the tag's i'th value as an integer. It returns an error if the +// tag's Format is not IntVal. It panics if i is out of range. +func (t *Tag) Int(i int) (int, error) { + if t.format != IntVal { + return 0, t.typeErr(IntVal) + } + return int(t.intVals[i]), nil +} + +// Float returns the tag's i'th value as a float. It returns an error if the +// tag's Format is not IntVal. It panics if i is out of range. +func (t *Tag) Float(i int) (float64, error) { + if t.format != FloatVal { + return 0, t.typeErr(FloatVal) + } + return t.floatVals[i], nil +} + +// StringVal returns the tag's value as a string. It returns an error if the +// tag's Format is not StringVal. It panics if i is out of range. +func (t *Tag) StringVal() (string, error) { + if t.format != StringVal { + return "", t.typeErr(StringVal) + } + return t.strVal, nil +} + +// String returns a nicely formatted version of the tag. +func (t *Tag) String() string { + data, err := t.MarshalJSON() + if err != nil { + return "ERROR: " + err.Error() + } + + if t.Count == 1 { + return strings.Trim(fmt.Sprintf("%s", data), "[]") + } + return fmt.Sprintf("%s", data) +} + +func (t *Tag) MarshalJSON() ([]byte, error) { + switch t.format { + case StringVal, UndefVal: + return nullString(t.Val), nil + case OtherVal: + return []byte(fmt.Sprintf("unknown tag type '%v'", t.Type)), nil + } + + rv := []string{} + for i := 0; i < int(t.Count); i++ { + switch t.format { + case RatVal: + n, d, _ := t.Rat2(i) + rv = append(rv, fmt.Sprintf(`"%v/%v"`, n, d)) + case FloatVal: + v, _ := t.Float(i) + rv = append(rv, fmt.Sprintf("%v", v)) + case IntVal: + v, _ := t.Int(i) + rv = append(rv, fmt.Sprintf("%v", v)) + } + } + return []byte(fmt.Sprintf(`[%s]`, strings.Join(rv, ","))), nil +} + +func nullString(in []byte) []byte { + rv := bytes.Buffer{} + rv.WriteByte('"') + for _, b := range in { + if unicode.IsPrint(rune(b)) { + rv.WriteByte(b) + } + } + rv.WriteByte('"') + rvb := rv.Bytes() + if utf8.Valid(rvb) { + return rvb + } + return []byte(`""`) +} + +type wrongFmtErr struct { + From, To string +} + +func (e *wrongFmtErr) Error() string { + return fmt.Sprintf("cannot convert tag type '%v' into '%v'", e.From, e.To) +} diff --git a/vendor/github.com/rwcarlsen/goexif/tiff/tiff.go b/vendor/github.com/rwcarlsen/goexif/tiff/tiff.go new file mode 100644 index 00000000..771e9187 --- /dev/null +++ b/vendor/github.com/rwcarlsen/goexif/tiff/tiff.go @@ -0,0 +1,153 @@ +// Package tiff implements TIFF decoding as defined in TIFF 6.0 specification at +// http://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf +package tiff + +import ( + "bytes" + "encoding/binary" + "errors" + "fmt" + "io" + "io/ioutil" +) + +// ReadAtReader is used when decoding Tiff tags and directories +type ReadAtReader interface { + io.Reader + io.ReaderAt +} + +// Tiff provides access to a decoded tiff data structure. +type Tiff struct { + // Dirs is an ordered slice of the tiff's Image File Directories (IFDs). + // The IFD at index 0 is IFD0. + Dirs []*Dir + // The tiff's byte-encoding (i.e. big/little endian). + Order binary.ByteOrder +} + +// Decode parses tiff-encoded data from r and returns a Tiff struct that +// reflects the structure and content of the tiff data. The first read from r +// should be the first byte of the tiff-encoded data and not necessarily the +// first byte of an os.File object. +func Decode(r io.Reader) (*Tiff, error) { + data, err := ioutil.ReadAll(r) + if err != nil { + return nil, errors.New("tiff: could not read data") + } + buf := bytes.NewReader(data) + + t := new(Tiff) + + // read byte order + bo := make([]byte, 2) + if _, err = io.ReadFull(buf, bo); err != nil { + return nil, errors.New("tiff: could not read tiff byte order") + } + if string(bo) == "II" { + t.Order = binary.LittleEndian + } else if string(bo) == "MM" { + t.Order = binary.BigEndian + } else { + return nil, errors.New("tiff: could not read tiff byte order") + } + + // check for special tiff marker + var sp int16 + err = binary.Read(buf, t.Order, &sp) + if err != nil || 42 != sp { + return nil, errors.New("tiff: could not find special tiff marker") + } + + // load offset to first IFD + var offset int32 + err = binary.Read(buf, t.Order, &offset) + if err != nil { + return nil, errors.New("tiff: could not read offset to first IFD") + } + + // load IFD's + var d *Dir + prev := offset + for offset != 0 { + // seek to offset + _, err := buf.Seek(int64(offset), 0) + if err != nil { + return nil, errors.New("tiff: seek to IFD failed") + } + + if buf.Len() == 0 { + return nil, errors.New("tiff: seek offset after EOF") + } + + // load the dir + d, offset, err = DecodeDir(buf, t.Order) + if err != nil { + return nil, err + } + + if offset == prev { + return nil, errors.New("tiff: recursive IFD") + } + prev = offset + + t.Dirs = append(t.Dirs, d) + } + + return t, nil +} + +func (tf *Tiff) String() string { + var buf bytes.Buffer + fmt.Fprint(&buf, "Tiff{") + for _, d := range tf.Dirs { + fmt.Fprintf(&buf, "%s, ", d.String()) + } + fmt.Fprintf(&buf, "}") + return buf.String() +} + +// Dir provides access to the parsed content of a tiff Image File Directory (IFD). +type Dir struct { + Tags []*Tag +} + +// DecodeDir parses a tiff-encoded IFD from r and returns a Dir object. offset +// is the offset to the next IFD. The first read from r should be at the first +// byte of the IFD. ReadAt offsets should generally be relative to the +// beginning of the tiff structure (not relative to the beginning of the IFD). +func DecodeDir(r ReadAtReader, order binary.ByteOrder) (d *Dir, offset int32, err error) { + d = new(Dir) + + // get num of tags in ifd + var nTags int16 + err = binary.Read(r, order, &nTags) + if err != nil { + return nil, 0, errors.New("tiff: failed to read IFD tag count: " + err.Error()) + } + + // load tags + for n := 0; n < int(nTags); n++ { + t, err := DecodeTag(r, order) + if err != nil { + return nil, 0, err + } + d.Tags = append(d.Tags, t) + } + + // get offset to next ifd + err = binary.Read(r, order, &offset) + if err != nil { + return nil, 0, errors.New("tiff: falied to read offset to next IFD: " + err.Error()) + } + + return d, offset, nil +} + +func (d *Dir) String() string { + s := "Dir{" + for _, t := range d.Tags { + s += t.String() + ", " + } + return s + "}" +} diff --git a/vendor/github.com/saintfish/chardet/2022.go b/vendor/github.com/saintfish/chardet/2022.go new file mode 100644 index 00000000..e667225e --- /dev/null +++ b/vendor/github.com/saintfish/chardet/2022.go @@ -0,0 +1,102 @@ +package chardet + +import ( + "bytes" +) + +type recognizer2022 struct { + charset string + escapes [][]byte +} + +func (r *recognizer2022) Match(input *recognizerInput) (output recognizerOutput) { + return recognizerOutput{ + Charset: r.charset, + Confidence: r.matchConfidence(input.input), + } +} + +func (r *recognizer2022) matchConfidence(input []byte) int { + var hits, misses, shifts int +input: + for i := 0; i < len(input); i++ { + c := input[i] + if c == 0x1B { + for _, esc := range r.escapes { + if bytes.HasPrefix(input[i+1:], esc) { + hits++ + i += len(esc) + continue input + } + } + misses++ + } else if c == 0x0E || c == 0x0F { + shifts++ + } + } + if hits == 0 { + return 0 + } + quality := (100*hits - 100*misses) / (hits + misses) + if hits+shifts < 5 { + quality -= (5 - (hits + shifts)) * 10 + } + if quality < 0 { + quality = 0 + } + return quality +} + +var escapeSequences_2022JP = [][]byte{ + {0x24, 0x28, 0x43}, // KS X 1001:1992 + {0x24, 0x28, 0x44}, // JIS X 212-1990 + {0x24, 0x40}, // JIS C 6226-1978 + {0x24, 0x41}, // GB 2312-80 + {0x24, 0x42}, // JIS X 208-1983 + {0x26, 0x40}, // JIS X 208 1990, 1997 + {0x28, 0x42}, // ASCII + {0x28, 0x48}, // JIS-Roman + {0x28, 0x49}, // Half-width katakana + {0x28, 0x4a}, // JIS-Roman + {0x2e, 0x41}, // ISO 8859-1 + {0x2e, 0x46}, // ISO 8859-7 +} + +var escapeSequences_2022KR = [][]byte{ + {0x24, 0x29, 0x43}, +} + +var escapeSequences_2022CN = [][]byte{ + {0x24, 0x29, 0x41}, // GB 2312-80 + {0x24, 0x29, 0x47}, // CNS 11643-1992 Plane 1 + {0x24, 0x2A, 0x48}, // CNS 11643-1992 Plane 2 + {0x24, 0x29, 0x45}, // ISO-IR-165 + {0x24, 0x2B, 0x49}, // CNS 11643-1992 Plane 3 + {0x24, 0x2B, 0x4A}, // CNS 11643-1992 Plane 4 + {0x24, 0x2B, 0x4B}, // CNS 11643-1992 Plane 5 + {0x24, 0x2B, 0x4C}, // CNS 11643-1992 Plane 6 + {0x24, 0x2B, 0x4D}, // CNS 11643-1992 Plane 7 + {0x4e}, // SS2 + {0x4f}, // SS3 +} + +func newRecognizer_2022JP() *recognizer2022 { + return &recognizer2022{ + "ISO-2022-JP", + escapeSequences_2022JP, + } +} + +func newRecognizer_2022KR() *recognizer2022 { + return &recognizer2022{ + "ISO-2022-KR", + escapeSequences_2022KR, + } +} + +func newRecognizer_2022CN() *recognizer2022 { + return &recognizer2022{ + "ISO-2022-CN", + escapeSequences_2022CN, + } +} diff --git a/vendor/github.com/saintfish/chardet/AUTHORS b/vendor/github.com/saintfish/chardet/AUTHORS new file mode 100644 index 00000000..842d0216 --- /dev/null +++ b/vendor/github.com/saintfish/chardet/AUTHORS @@ -0,0 +1 @@ +Sheng Yu (yusheng dot sjtu at gmail dot com) diff --git a/vendor/github.com/saintfish/chardet/LICENSE b/vendor/github.com/saintfish/chardet/LICENSE new file mode 100644 index 00000000..35ee796b --- /dev/null +++ b/vendor/github.com/saintfish/chardet/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2012 chardet Authors + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +Partial of the Software is derived from ICU project. See icu-license.html for +license of the derivative portions. diff --git a/vendor/github.com/saintfish/chardet/README.md b/vendor/github.com/saintfish/chardet/README.md new file mode 100644 index 00000000..41f58ee0 --- /dev/null +++ b/vendor/github.com/saintfish/chardet/README.md @@ -0,0 +1,10 @@ +# chardet + +chardet is library to automatically detect +[charset](http://en.wikipedia.org/wiki/Character_encoding) of texts for [Go +programming language](http://golang.org/). It's based on the algorithm and data +in [ICU](http://icu-project.org/)'s implementation. + +## Documentation and Usage + +See [pkgdoc](https://pkg.go.dev/github.com/saintfish/chardet) diff --git a/vendor/github.com/saintfish/chardet/detector.go b/vendor/github.com/saintfish/chardet/detector.go new file mode 100644 index 00000000..e11c222e --- /dev/null +++ b/vendor/github.com/saintfish/chardet/detector.go @@ -0,0 +1,136 @@ +// Package chardet ports character set detection from ICU. +package chardet + +import ( + "errors" + "sort" +) + +// Result contains all the information that charset detector gives. +type Result struct { + // IANA name of the detected charset. + Charset string + // IANA name of the detected language. It may be empty for some charsets. + Language string + // Confidence of the Result. Scale from 1 to 100. The bigger, the more confident. + Confidence int +} + +// Detector implements charset detection. +type Detector struct { + recognizers []recognizer + stripTag bool +} + +// List of charset recognizers +var recognizers = []recognizer{ + newRecognizer_utf8(), + newRecognizer_utf16be(), + newRecognizer_utf16le(), + newRecognizer_utf32be(), + newRecognizer_utf32le(), + newRecognizer_8859_1_en(), + newRecognizer_8859_1_da(), + newRecognizer_8859_1_de(), + newRecognizer_8859_1_es(), + newRecognizer_8859_1_fr(), + newRecognizer_8859_1_it(), + newRecognizer_8859_1_nl(), + newRecognizer_8859_1_no(), + newRecognizer_8859_1_pt(), + newRecognizer_8859_1_sv(), + newRecognizer_8859_2_cs(), + newRecognizer_8859_2_hu(), + newRecognizer_8859_2_pl(), + newRecognizer_8859_2_ro(), + newRecognizer_8859_5_ru(), + newRecognizer_8859_6_ar(), + newRecognizer_8859_7_el(), + newRecognizer_8859_8_I_he(), + newRecognizer_8859_8_he(), + newRecognizer_windows_1251(), + newRecognizer_windows_1256(), + newRecognizer_KOI8_R(), + newRecognizer_8859_9_tr(), + + newRecognizer_sjis(), + newRecognizer_gb_18030(), + newRecognizer_euc_jp(), + newRecognizer_euc_kr(), + newRecognizer_big5(), + + newRecognizer_2022JP(), + newRecognizer_2022KR(), + newRecognizer_2022CN(), + + newRecognizer_IBM424_he_rtl(), + newRecognizer_IBM424_he_ltr(), + newRecognizer_IBM420_ar_rtl(), + newRecognizer_IBM420_ar_ltr(), +} + +// NewTextDetector creates a Detector for plain text. +func NewTextDetector() *Detector { + return &Detector{recognizers, false} +} + +// NewHtmlDetector creates a Detector for Html. +func NewHtmlDetector() *Detector { + return &Detector{recognizers, true} +} + +var ( + NotDetectedError = errors.New("Charset not detected.") +) + +// DetectBest returns the Result with highest Confidence. +func (d *Detector) DetectBest(b []byte) (r *Result, err error) { + var all []Result + if all, err = d.DetectAll(b); err == nil { + r = &all[0] + } + return +} + +// DetectAll returns all Results which have non-zero Confidence. The Results are sorted by Confidence in descending order. +func (d *Detector) DetectAll(b []byte) ([]Result, error) { + input := newRecognizerInput(b, d.stripTag) + outputChan := make(chan recognizerOutput) + for _, r := range d.recognizers { + go matchHelper(r, input, outputChan) + } + outputs := make([]recognizerOutput, 0, len(d.recognizers)) + for i := 0; i < len(d.recognizers); i++ { + o := <-outputChan + if o.Confidence > 0 { + outputs = append(outputs, o) + } + } + if len(outputs) == 0 { + return nil, NotDetectedError + } + + sort.Sort(recognizerOutputs(outputs)) + dedupOutputs := make([]Result, 0, len(outputs)) + foundCharsets := make(map[string]struct{}, len(outputs)) + for _, o := range outputs { + if _, found := foundCharsets[o.Charset]; !found { + dedupOutputs = append(dedupOutputs, Result(o)) + foundCharsets[o.Charset] = struct{}{} + } + } + if len(dedupOutputs) == 0 { + return nil, NotDetectedError + } + return dedupOutputs, nil +} + +func matchHelper(r recognizer, input *recognizerInput, outputChan chan<- recognizerOutput) { + outputChan <- r.Match(input) +} + +type recognizerOutputs []recognizerOutput + +func (r recognizerOutputs) Len() int { return len(r) } +func (r recognizerOutputs) Less(i, j int) bool { return r[i].Confidence > r[j].Confidence } +func (r recognizerOutputs) Swap(i, j int) { r[i], r[j] = r[j], r[i] } diff --git a/vendor/github.com/saintfish/chardet/icu-license.html b/vendor/github.com/saintfish/chardet/icu-license.html new file mode 100644 index 00000000..d078d057 --- /dev/null +++ b/vendor/github.com/saintfish/chardet/icu-license.html @@ -0,0 +1,51 @@ + + + + +ICU License - ICU 1.8.1 and later + + + +

ICU License - ICU 1.8.1 and later

+ +

COPYRIGHT AND PERMISSION NOTICE

+ +

+Copyright (c) 1995-2012 International Business Machines Corporation and others +

+

+All rights reserved. +

+

+Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, and/or sell +copies of the Software, and to permit persons +to whom the Software is furnished to do so, provided that the above +copyright notice(s) and this permission notice appear in all copies +of the Software and that both the above copyright notice(s) and this +permission notice appear in supporting documentation. +

+

+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL +THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, +OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE +USE OR PERFORMANCE OF THIS SOFTWARE. +

+

+Except as contained in this notice, the name of a copyright holder shall not be +used in advertising or otherwise to promote the sale, use or other dealings in +this Software without prior written authorization of the copyright holder. +

+ +
+

+All trademarks and registered trademarks mentioned herein are the property of their respective owners. +

+ + diff --git a/vendor/github.com/saintfish/chardet/multi_byte.go b/vendor/github.com/saintfish/chardet/multi_byte.go new file mode 100644 index 00000000..1fab34ce --- /dev/null +++ b/vendor/github.com/saintfish/chardet/multi_byte.go @@ -0,0 +1,345 @@ +package chardet + +import ( + "errors" + "math" +) + +type recognizerMultiByte struct { + charset string + language string + decoder charDecoder + commonChars []uint16 +} + +type charDecoder interface { + DecodeOneChar([]byte) (c uint16, remain []byte, err error) +} + +func (r *recognizerMultiByte) Match(input *recognizerInput) (output recognizerOutput) { + return recognizerOutput{ + Charset: r.charset, + Language: r.language, + Confidence: r.matchConfidence(input), + } +} + +func (r *recognizerMultiByte) matchConfidence(input *recognizerInput) int { + raw := input.raw + var c uint16 + var err error + var totalCharCount, badCharCount, singleByteCharCount, doubleByteCharCount, commonCharCount int + for c, raw, err = r.decoder.DecodeOneChar(raw); len(raw) > 0; c, raw, err = r.decoder.DecodeOneChar(raw) { + totalCharCount++ + if err != nil { + badCharCount++ + } else if c <= 0xFF { + singleByteCharCount++ + } else { + doubleByteCharCount++ + if r.commonChars != nil && binarySearch(r.commonChars, c) { + commonCharCount++ + } + } + if badCharCount >= 2 && badCharCount*5 >= doubleByteCharCount { + return 0 + } + } + + if doubleByteCharCount <= 10 && badCharCount == 0 { + if doubleByteCharCount == 0 && totalCharCount < 10 { + return 0 + } else { + return 10 + } + } + + if doubleByteCharCount < 20*badCharCount { + return 0 + } + if r.commonChars == nil { + confidence := 30 + doubleByteCharCount - 20*badCharCount + if confidence > 100 { + confidence = 100 + } + return confidence + } + maxVal := math.Log(float64(doubleByteCharCount) / 4) + scaleFactor := 90 / maxVal + confidence := int(math.Log(float64(commonCharCount)+1)*scaleFactor + 10) + if confidence > 100 { + confidence = 100 + } + if confidence < 0 { + confidence = 0 + } + return confidence +} + +func binarySearch(l []uint16, c uint16) bool { + start := 0 + end := len(l) - 1 + for start <= end { + mid := (start + end) / 2 + if c == l[mid] { + return true + } else if c < l[mid] { + end = mid - 1 + } else { + start = mid + 1 + } + } + return false +} + +var eobError = errors.New("End of input buffer") +var badCharError = errors.New("Decode a bad char") + +type charDecoder_sjis struct { +} + +func (charDecoder_sjis) DecodeOneChar(input []byte) (c uint16, remain []byte, err error) { + if len(input) == 0 { + return 0, nil, eobError + } + first := input[0] + c = uint16(first) + remain = input[1:] + if first <= 0x7F || (first > 0xA0 && first <= 0xDF) { + return + } + if len(remain) == 0 { + return c, remain, badCharError + } + second := remain[0] + remain = remain[1:] + c = c<<8 | uint16(second) + if (second >= 0x40 && second <= 0x7F) || (second >= 0x80 && second <= 0xFE) { + } else { + err = badCharError + } + return +} + +var commonChars_sjis = []uint16{ + 0x8140, 0x8141, 0x8142, 0x8145, 0x815b, 0x8169, 0x816a, 0x8175, 0x8176, 0x82a0, + 0x82a2, 0x82a4, 0x82a9, 0x82aa, 0x82ab, 0x82ad, 0x82af, 0x82b1, 0x82b3, 0x82b5, + 0x82b7, 0x82bd, 0x82be, 0x82c1, 0x82c4, 0x82c5, 0x82c6, 0x82c8, 0x82c9, 0x82cc, + 0x82cd, 0x82dc, 0x82e0, 0x82e7, 0x82e8, 0x82e9, 0x82ea, 0x82f0, 0x82f1, 0x8341, + 0x8343, 0x834e, 0x834f, 0x8358, 0x835e, 0x8362, 0x8367, 0x8375, 0x8376, 0x8389, + 0x838a, 0x838b, 0x838d, 0x8393, 0x8e96, 0x93fa, 0x95aa, +} + +func newRecognizer_sjis() *recognizerMultiByte { + return &recognizerMultiByte{ + "Shift_JIS", + "ja", + charDecoder_sjis{}, + commonChars_sjis, + } +} + +type charDecoder_euc struct { +} + +func (charDecoder_euc) DecodeOneChar(input []byte) (c uint16, remain []byte, err error) { + if len(input) == 0 { + return 0, nil, eobError + } + first := input[0] + remain = input[1:] + c = uint16(first) + if first <= 0x8D { + return uint16(first), remain, nil + } + if len(remain) == 0 { + return 0, nil, eobError + } + second := remain[0] + remain = remain[1:] + c = c<<8 | uint16(second) + if first >= 0xA1 && first <= 0xFE { + if second < 0xA1 { + err = badCharError + } + return + } + if first == 0x8E { + if second < 0xA1 { + err = badCharError + } + return + } + if first == 0x8F { + if len(remain) == 0 { + return 0, nil, eobError + } + third := remain[0] + remain = remain[1:] + c = c<<0 | uint16(third) + if third < 0xa1 { + err = badCharError + } + } + return +} + +var commonChars_euc_jp = []uint16{ + 0xa1a1, 0xa1a2, 0xa1a3, 0xa1a6, 0xa1bc, 0xa1ca, 0xa1cb, 0xa1d6, 0xa1d7, 0xa4a2, + 0xa4a4, 0xa4a6, 0xa4a8, 0xa4aa, 0xa4ab, 0xa4ac, 0xa4ad, 0xa4af, 0xa4b1, 0xa4b3, + 0xa4b5, 0xa4b7, 0xa4b9, 0xa4bb, 0xa4bd, 0xa4bf, 0xa4c0, 0xa4c1, 0xa4c3, 0xa4c4, + 0xa4c6, 0xa4c7, 0xa4c8, 0xa4c9, 0xa4ca, 0xa4cb, 0xa4ce, 0xa4cf, 0xa4d0, 0xa4de, + 0xa4df, 0xa4e1, 0xa4e2, 0xa4e4, 0xa4e8, 0xa4e9, 0xa4ea, 0xa4eb, 0xa4ec, 0xa4ef, + 0xa4f2, 0xa4f3, 0xa5a2, 0xa5a3, 0xa5a4, 0xa5a6, 0xa5a7, 0xa5aa, 0xa5ad, 0xa5af, + 0xa5b0, 0xa5b3, 0xa5b5, 0xa5b7, 0xa5b8, 0xa5b9, 0xa5bf, 0xa5c3, 0xa5c6, 0xa5c7, + 0xa5c8, 0xa5c9, 0xa5cb, 0xa5d0, 0xa5d5, 0xa5d6, 0xa5d7, 0xa5de, 0xa5e0, 0xa5e1, + 0xa5e5, 0xa5e9, 0xa5ea, 0xa5eb, 0xa5ec, 0xa5ed, 0xa5f3, 0xb8a9, 0xb9d4, 0xbaee, + 0xbbc8, 0xbef0, 0xbfb7, 0xc4ea, 0xc6fc, 0xc7bd, 0xcab8, 0xcaf3, 0xcbdc, 0xcdd1, +} + +var commonChars_euc_kr = []uint16{ + 0xb0a1, 0xb0b3, 0xb0c5, 0xb0cd, 0xb0d4, 0xb0e6, 0xb0ed, 0xb0f8, 0xb0fa, 0xb0fc, + 0xb1b8, 0xb1b9, 0xb1c7, 0xb1d7, 0xb1e2, 0xb3aa, 0xb3bb, 0xb4c2, 0xb4cf, 0xb4d9, + 0xb4eb, 0xb5a5, 0xb5b5, 0xb5bf, 0xb5c7, 0xb5e9, 0xb6f3, 0xb7af, 0xb7c2, 0xb7ce, + 0xb8a6, 0xb8ae, 0xb8b6, 0xb8b8, 0xb8bb, 0xb8e9, 0xb9ab, 0xb9ae, 0xb9cc, 0xb9ce, + 0xb9fd, 0xbab8, 0xbace, 0xbad0, 0xbaf1, 0xbbe7, 0xbbf3, 0xbbfd, 0xbcad, 0xbcba, + 0xbcd2, 0xbcf6, 0xbdba, 0xbdc0, 0xbdc3, 0xbdc5, 0xbec6, 0xbec8, 0xbedf, 0xbeee, + 0xbef8, 0xbefa, 0xbfa1, 0xbfa9, 0xbfc0, 0xbfe4, 0xbfeb, 0xbfec, 0xbff8, 0xc0a7, + 0xc0af, 0xc0b8, 0xc0ba, 0xc0bb, 0xc0bd, 0xc0c7, 0xc0cc, 0xc0ce, 0xc0cf, 0xc0d6, + 0xc0da, 0xc0e5, 0xc0fb, 0xc0fc, 0xc1a4, 0xc1a6, 0xc1b6, 0xc1d6, 0xc1df, 0xc1f6, + 0xc1f8, 0xc4a1, 0xc5cd, 0xc6ae, 0xc7cf, 0xc7d1, 0xc7d2, 0xc7d8, 0xc7e5, 0xc8ad, +} + +func newRecognizer_euc_jp() *recognizerMultiByte { + return &recognizerMultiByte{ + "EUC-JP", + "ja", + charDecoder_euc{}, + commonChars_euc_jp, + } +} + +func newRecognizer_euc_kr() *recognizerMultiByte { + return &recognizerMultiByte{ + "EUC-KR", + "ko", + charDecoder_euc{}, + commonChars_euc_kr, + } +} + +type charDecoder_big5 struct { +} + +func (charDecoder_big5) DecodeOneChar(input []byte) (c uint16, remain []byte, err error) { + if len(input) == 0 { + return 0, nil, eobError + } + first := input[0] + remain = input[1:] + c = uint16(first) + if first <= 0x7F || first == 0xFF { + return + } + if len(remain) == 0 { + return c, nil, eobError + } + second := remain[0] + remain = remain[1:] + c = c<<8 | uint16(second) + if second < 0x40 || second == 0x7F || second == 0xFF { + err = badCharError + } + return +} + +var commonChars_big5 = []uint16{ + 0xa140, 0xa141, 0xa142, 0xa143, 0xa147, 0xa149, 0xa175, 0xa176, 0xa440, 0xa446, + 0xa447, 0xa448, 0xa451, 0xa454, 0xa457, 0xa464, 0xa46a, 0xa46c, 0xa477, 0xa4a3, + 0xa4a4, 0xa4a7, 0xa4c1, 0xa4ce, 0xa4d1, 0xa4df, 0xa4e8, 0xa4fd, 0xa540, 0xa548, + 0xa558, 0xa569, 0xa5cd, 0xa5e7, 0xa657, 0xa661, 0xa662, 0xa668, 0xa670, 0xa6a8, + 0xa6b3, 0xa6b9, 0xa6d3, 0xa6db, 0xa6e6, 0xa6f2, 0xa740, 0xa751, 0xa759, 0xa7da, + 0xa8a3, 0xa8a5, 0xa8ad, 0xa8d1, 0xa8d3, 0xa8e4, 0xa8fc, 0xa9c0, 0xa9d2, 0xa9f3, + 0xaa6b, 0xaaba, 0xaabe, 0xaacc, 0xaafc, 0xac47, 0xac4f, 0xacb0, 0xacd2, 0xad59, + 0xaec9, 0xafe0, 0xb0ea, 0xb16f, 0xb2b3, 0xb2c4, 0xb36f, 0xb44c, 0xb44e, 0xb54c, + 0xb5a5, 0xb5bd, 0xb5d0, 0xb5d8, 0xb671, 0xb7ed, 0xb867, 0xb944, 0xbad8, 0xbb44, + 0xbba1, 0xbdd1, 0xc2c4, 0xc3b9, 0xc440, 0xc45f, +} + +func newRecognizer_big5() *recognizerMultiByte { + return &recognizerMultiByte{ + "Big5", + "zh", + charDecoder_big5{}, + commonChars_big5, + } +} + +type charDecoder_gb_18030 struct { +} + +func (charDecoder_gb_18030) DecodeOneChar(input []byte) (c uint16, remain []byte, err error) { + if len(input) == 0 { + return 0, nil, eobError + } + first := input[0] + remain = input[1:] + c = uint16(first) + if first <= 0x80 { + return + } + if len(remain) == 0 { + return 0, nil, eobError + } + second := remain[0] + remain = remain[1:] + c = c<<8 | uint16(second) + if first >= 0x81 && first <= 0xFE { + if (second >= 0x40 && second <= 0x7E) || (second >= 0x80 && second <= 0xFE) { + return + } + + if second >= 0x30 && second <= 0x39 { + if len(remain) == 0 { + return 0, nil, eobError + } + third := remain[0] + remain = remain[1:] + if third >= 0x81 && third <= 0xFE { + if len(remain) == 0 { + return 0, nil, eobError + } + fourth := remain[0] + remain = remain[1:] + if fourth >= 0x30 && fourth <= 0x39 { + c = c<<16 | uint16(third)<<8 | uint16(fourth) + return + } + } + } + err = badCharError + } + return +} + +var commonChars_gb_18030 = []uint16{ + 0xa1a1, 0xa1a2, 0xa1a3, 0xa1a4, 0xa1b0, 0xa1b1, 0xa1f1, 0xa1f3, 0xa3a1, 0xa3ac, + 0xa3ba, 0xb1a8, 0xb1b8, 0xb1be, 0xb2bb, 0xb3c9, 0xb3f6, 0xb4f3, 0xb5bd, 0xb5c4, + 0xb5e3, 0xb6af, 0xb6d4, 0xb6e0, 0xb7a2, 0xb7a8, 0xb7bd, 0xb7d6, 0xb7dd, 0xb8b4, + 0xb8df, 0xb8f6, 0xb9ab, 0xb9c9, 0xb9d8, 0xb9fa, 0xb9fd, 0xbacd, 0xbba7, 0xbbd6, + 0xbbe1, 0xbbfa, 0xbcbc, 0xbcdb, 0xbcfe, 0xbdcc, 0xbecd, 0xbedd, 0xbfb4, 0xbfc6, + 0xbfc9, 0xc0b4, 0xc0ed, 0xc1cb, 0xc2db, 0xc3c7, 0xc4dc, 0xc4ea, 0xc5cc, 0xc6f7, + 0xc7f8, 0xc8ab, 0xc8cb, 0xc8d5, 0xc8e7, 0xc9cf, 0xc9fa, 0xcab1, 0xcab5, 0xcac7, + 0xcad0, 0xcad6, 0xcaf5, 0xcafd, 0xccec, 0xcdf8, 0xceaa, 0xcec4, 0xced2, 0xcee5, + 0xcfb5, 0xcfc2, 0xcfd6, 0xd0c2, 0xd0c5, 0xd0d0, 0xd0d4, 0xd1a7, 0xd2aa, 0xd2b2, + 0xd2b5, 0xd2bb, 0xd2d4, 0xd3c3, 0xd3d0, 0xd3fd, 0xd4c2, 0xd4da, 0xd5e2, 0xd6d0, +} + +func newRecognizer_gb_18030() *recognizerMultiByte { + return &recognizerMultiByte{ + "GB-18030", + "zh", + charDecoder_gb_18030{}, + commonChars_gb_18030, + } +} diff --git a/vendor/github.com/saintfish/chardet/recognizer.go b/vendor/github.com/saintfish/chardet/recognizer.go new file mode 100644 index 00000000..1bf8461c --- /dev/null +++ b/vendor/github.com/saintfish/chardet/recognizer.go @@ -0,0 +1,83 @@ +package chardet + +type recognizer interface { + Match(*recognizerInput) recognizerOutput +} + +type recognizerOutput Result + +type recognizerInput struct { + raw []byte + input []byte + tagStripped bool + byteStats []int + hasC1Bytes bool +} + +func newRecognizerInput(raw []byte, stripTag bool) *recognizerInput { + input, stripped := mayStripInput(raw, stripTag) + byteStats := computeByteStats(input) + return &recognizerInput{ + raw: raw, + input: input, + tagStripped: stripped, + byteStats: byteStats, + hasC1Bytes: computeHasC1Bytes(byteStats), + } +} + +func mayStripInput(raw []byte, stripTag bool) (out []byte, stripped bool) { + const inputBufferSize = 8192 + out = make([]byte, 0, inputBufferSize) + var badTags, openTags int32 + var inMarkup bool = false + stripped = false + if stripTag { + stripped = true + for _, c := range raw { + if c == '<' { + if inMarkup { + badTags += 1 + } + inMarkup = true + openTags += 1 + } + if !inMarkup { + out = append(out, c) + if len(out) >= inputBufferSize { + break + } + } + if c == '>' { + inMarkup = false + } + } + } + if openTags < 5 || openTags/5 < badTags || (len(out) < 100 && len(raw) > 600) { + limit := len(raw) + if limit > inputBufferSize { + limit = inputBufferSize + } + out = make([]byte, limit) + copy(out, raw[:limit]) + stripped = false + } + return +} + +func computeByteStats(input []byte) []int { + r := make([]int, 256) + for _, c := range input { + r[c] += 1 + } + return r +} + +func computeHasC1Bytes(byteStats []int) bool { + for _, count := range byteStats[0x80 : 0x9F+1] { + if count > 0 { + return true + } + } + return false +} diff --git a/vendor/github.com/saintfish/chardet/single_byte.go b/vendor/github.com/saintfish/chardet/single_byte.go new file mode 100644 index 00000000..efe41c90 --- /dev/null +++ b/vendor/github.com/saintfish/chardet/single_byte.go @@ -0,0 +1,882 @@ +package chardet + +// Recognizer for single byte charset family +type recognizerSingleByte struct { + charset string + hasC1ByteCharset string + language string + charMap *[256]byte + ngram *[64]uint32 +} + +func (r *recognizerSingleByte) Match(input *recognizerInput) recognizerOutput { + var charset string = r.charset + if input.hasC1Bytes && len(r.hasC1ByteCharset) > 0 { + charset = r.hasC1ByteCharset + } + return recognizerOutput{ + Charset: charset, + Language: r.language, + Confidence: r.parseNgram(input.input), + } +} + +type ngramState struct { + ngram uint32 + ignoreSpace bool + ngramCount, ngramHit uint32 + table *[64]uint32 +} + +func newNgramState(table *[64]uint32) *ngramState { + return &ngramState{ + ngram: 0, + ignoreSpace: false, + ngramCount: 0, + ngramHit: 0, + table: table, + } +} + +func (s *ngramState) AddByte(b byte) { + const ngramMask = 0xFFFFFF + if !(b == 0x20 && s.ignoreSpace) { + s.ngram = ((s.ngram << 8) | uint32(b)) & ngramMask + s.ignoreSpace = (s.ngram == 0x20) + s.ngramCount++ + if s.lookup() { + s.ngramHit++ + } + } + s.ignoreSpace = (b == 0x20) +} + +func (s *ngramState) HitRate() float32 { + if s.ngramCount == 0 { + return 0 + } + return float32(s.ngramHit) / float32(s.ngramCount) +} + +func (s *ngramState) lookup() bool { + var index int + if s.table[index+32] <= s.ngram { + index += 32 + } + if s.table[index+16] <= s.ngram { + index += 16 + } + if s.table[index+8] <= s.ngram { + index += 8 + } + if s.table[index+4] <= s.ngram { + index += 4 + } + if s.table[index+2] <= s.ngram { + index += 2 + } + if s.table[index+1] <= s.ngram { + index += 1 + } + if s.table[index] > s.ngram { + index -= 1 + } + if index < 0 || s.table[index] != s.ngram { + return false + } + return true +} + +func (r *recognizerSingleByte) parseNgram(input []byte) int { + state := newNgramState(r.ngram) + for _, inChar := range input { + c := r.charMap[inChar] + if c != 0 { + state.AddByte(c) + } + } + state.AddByte(0x20) + rate := state.HitRate() + if rate > 0.33 { + return 98 + } + return int(rate * 300) +} + +var charMap_8859_1 = [256]byte{ + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0xAA, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0xB5, 0x20, 0x20, + 0x20, 0x20, 0xBA, 0x20, 0x20, 0x20, 0x20, 0x20, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0x20, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0x20, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, +} + +var ngrams_8859_1_en = [64]uint32{ + 0x206120, 0x20616E, 0x206265, 0x20636F, 0x20666F, 0x206861, 0x206865, 0x20696E, 0x206D61, 0x206F66, 0x207072, 0x207265, 0x207361, 0x207374, 0x207468, 0x20746F, + 0x207768, 0x616964, 0x616C20, 0x616E20, 0x616E64, 0x617320, 0x617420, 0x617465, 0x617469, 0x642061, 0x642074, 0x652061, 0x652073, 0x652074, 0x656420, 0x656E74, + 0x657220, 0x657320, 0x666F72, 0x686174, 0x686520, 0x686572, 0x696420, 0x696E20, 0x696E67, 0x696F6E, 0x697320, 0x6E2061, 0x6E2074, 0x6E6420, 0x6E6720, 0x6E7420, + 0x6F6620, 0x6F6E20, 0x6F7220, 0x726520, 0x727320, 0x732061, 0x732074, 0x736169, 0x737420, 0x742074, 0x746572, 0x746861, 0x746865, 0x74696F, 0x746F20, 0x747320, +} + +var ngrams_8859_1_da = [64]uint32{ + 0x206166, 0x206174, 0x206465, 0x20656E, 0x206572, 0x20666F, 0x206861, 0x206920, 0x206D65, 0x206F67, 0x2070E5, 0x207369, 0x207374, 0x207469, 0x207669, 0x616620, + 0x616E20, 0x616E64, 0x617220, 0x617420, 0x646520, 0x64656E, 0x646572, 0x646574, 0x652073, 0x656420, 0x656465, 0x656E20, 0x656E64, 0x657220, 0x657265, 0x657320, + 0x657420, 0x666F72, 0x676520, 0x67656E, 0x676572, 0x696765, 0x696C20, 0x696E67, 0x6B6520, 0x6B6B65, 0x6C6572, 0x6C6967, 0x6C6C65, 0x6D6564, 0x6E6465, 0x6E6520, + 0x6E6720, 0x6E6765, 0x6F6720, 0x6F6D20, 0x6F7220, 0x70E520, 0x722064, 0x722065, 0x722073, 0x726520, 0x737465, 0x742073, 0x746520, 0x746572, 0x74696C, 0x766572, +} + +var ngrams_8859_1_de = [64]uint32{ + 0x20616E, 0x206175, 0x206265, 0x206461, 0x206465, 0x206469, 0x206569, 0x206765, 0x206861, 0x20696E, 0x206D69, 0x207363, 0x207365, 0x20756E, 0x207665, 0x20766F, + 0x207765, 0x207A75, 0x626572, 0x636820, 0x636865, 0x636874, 0x646173, 0x64656E, 0x646572, 0x646965, 0x652064, 0x652073, 0x65696E, 0x656974, 0x656E20, 0x657220, + 0x657320, 0x67656E, 0x68656E, 0x687420, 0x696368, 0x696520, 0x696E20, 0x696E65, 0x697420, 0x6C6963, 0x6C6C65, 0x6E2061, 0x6E2064, 0x6E2073, 0x6E6420, 0x6E6465, + 0x6E6520, 0x6E6720, 0x6E6765, 0x6E7465, 0x722064, 0x726465, 0x726569, 0x736368, 0x737465, 0x742064, 0x746520, 0x74656E, 0x746572, 0x756E64, 0x756E67, 0x766572, +} + +var ngrams_8859_1_es = [64]uint32{ + 0x206120, 0x206361, 0x20636F, 0x206465, 0x20656C, 0x20656E, 0x206573, 0x20696E, 0x206C61, 0x206C6F, 0x207061, 0x20706F, 0x207072, 0x207175, 0x207265, 0x207365, + 0x20756E, 0x207920, 0x612063, 0x612064, 0x612065, 0x61206C, 0x612070, 0x616369, 0x61646F, 0x616C20, 0x617220, 0x617320, 0x6369F3, 0x636F6E, 0x646520, 0x64656C, + 0x646F20, 0x652064, 0x652065, 0x65206C, 0x656C20, 0x656E20, 0x656E74, 0x657320, 0x657374, 0x69656E, 0x69F36E, 0x6C6120, 0x6C6F73, 0x6E2065, 0x6E7465, 0x6F2064, + 0x6F2065, 0x6F6E20, 0x6F7220, 0x6F7320, 0x706172, 0x717565, 0x726120, 0x726573, 0x732064, 0x732065, 0x732070, 0x736520, 0x746520, 0x746F20, 0x756520, 0xF36E20, +} + +var ngrams_8859_1_fr = [64]uint32{ + 0x206175, 0x20636F, 0x206461, 0x206465, 0x206475, 0x20656E, 0x206574, 0x206C61, 0x206C65, 0x207061, 0x20706F, 0x207072, 0x207175, 0x207365, 0x20736F, 0x20756E, + 0x20E020, 0x616E74, 0x617469, 0x636520, 0x636F6E, 0x646520, 0x646573, 0x647520, 0x652061, 0x652063, 0x652064, 0x652065, 0x65206C, 0x652070, 0x652073, 0x656E20, + 0x656E74, 0x657220, 0x657320, 0x657420, 0x657572, 0x696F6E, 0x697320, 0x697420, 0x6C6120, 0x6C6520, 0x6C6573, 0x6D656E, 0x6E2064, 0x6E6520, 0x6E7320, 0x6E7420, + 0x6F6E20, 0x6F6E74, 0x6F7572, 0x717565, 0x72206C, 0x726520, 0x732061, 0x732064, 0x732065, 0x73206C, 0x732070, 0x742064, 0x746520, 0x74696F, 0x756520, 0x757220, +} + +var ngrams_8859_1_it = [64]uint32{ + 0x20616C, 0x206368, 0x20636F, 0x206465, 0x206469, 0x206520, 0x20696C, 0x20696E, 0x206C61, 0x207065, 0x207072, 0x20756E, 0x612063, 0x612064, 0x612070, 0x612073, + 0x61746F, 0x636865, 0x636F6E, 0x64656C, 0x646920, 0x652061, 0x652063, 0x652064, 0x652069, 0x65206C, 0x652070, 0x652073, 0x656C20, 0x656C6C, 0x656E74, 0x657220, + 0x686520, 0x692061, 0x692063, 0x692064, 0x692073, 0x696120, 0x696C20, 0x696E20, 0x696F6E, 0x6C6120, 0x6C6520, 0x6C6920, 0x6C6C61, 0x6E6520, 0x6E6920, 0x6E6F20, + 0x6E7465, 0x6F2061, 0x6F2064, 0x6F2069, 0x6F2073, 0x6F6E20, 0x6F6E65, 0x706572, 0x726120, 0x726520, 0x736920, 0x746120, 0x746520, 0x746920, 0x746F20, 0x7A696F, +} + +var ngrams_8859_1_nl = [64]uint32{ + 0x20616C, 0x206265, 0x206461, 0x206465, 0x206469, 0x206565, 0x20656E, 0x206765, 0x206865, 0x20696E, 0x206D61, 0x206D65, 0x206F70, 0x207465, 0x207661, 0x207665, + 0x20766F, 0x207765, 0x207A69, 0x61616E, 0x616172, 0x616E20, 0x616E64, 0x617220, 0x617420, 0x636874, 0x646520, 0x64656E, 0x646572, 0x652062, 0x652076, 0x65656E, + 0x656572, 0x656E20, 0x657220, 0x657273, 0x657420, 0x67656E, 0x686574, 0x696520, 0x696E20, 0x696E67, 0x697320, 0x6E2062, 0x6E2064, 0x6E2065, 0x6E2068, 0x6E206F, + 0x6E2076, 0x6E6465, 0x6E6720, 0x6F6E64, 0x6F6F72, 0x6F7020, 0x6F7220, 0x736368, 0x737465, 0x742064, 0x746520, 0x74656E, 0x746572, 0x76616E, 0x766572, 0x766F6F, +} + +var ngrams_8859_1_no = [64]uint32{ + 0x206174, 0x206176, 0x206465, 0x20656E, 0x206572, 0x20666F, 0x206861, 0x206920, 0x206D65, 0x206F67, 0x2070E5, 0x207365, 0x20736B, 0x20736F, 0x207374, 0x207469, + 0x207669, 0x20E520, 0x616E64, 0x617220, 0x617420, 0x646520, 0x64656E, 0x646574, 0x652073, 0x656420, 0x656E20, 0x656E65, 0x657220, 0x657265, 0x657420, 0x657474, + 0x666F72, 0x67656E, 0x696B6B, 0x696C20, 0x696E67, 0x6B6520, 0x6B6B65, 0x6C6520, 0x6C6C65, 0x6D6564, 0x6D656E, 0x6E2073, 0x6E6520, 0x6E6720, 0x6E6765, 0x6E6E65, + 0x6F6720, 0x6F6D20, 0x6F7220, 0x70E520, 0x722073, 0x726520, 0x736F6D, 0x737465, 0x742073, 0x746520, 0x74656E, 0x746572, 0x74696C, 0x747420, 0x747465, 0x766572, +} + +var ngrams_8859_1_pt = [64]uint32{ + 0x206120, 0x20636F, 0x206461, 0x206465, 0x20646F, 0x206520, 0x206573, 0x206D61, 0x206E6F, 0x206F20, 0x207061, 0x20706F, 0x207072, 0x207175, 0x207265, 0x207365, + 0x20756D, 0x612061, 0x612063, 0x612064, 0x612070, 0x616465, 0x61646F, 0x616C20, 0x617220, 0x617261, 0x617320, 0x636F6D, 0x636F6E, 0x646120, 0x646520, 0x646F20, + 0x646F73, 0x652061, 0x652064, 0x656D20, 0x656E74, 0x657320, 0x657374, 0x696120, 0x696361, 0x6D656E, 0x6E7465, 0x6E746F, 0x6F2061, 0x6F2063, 0x6F2064, 0x6F2065, + 0x6F2070, 0x6F7320, 0x706172, 0x717565, 0x726120, 0x726573, 0x732061, 0x732064, 0x732065, 0x732070, 0x737461, 0x746520, 0x746F20, 0x756520, 0xE36F20, 0xE7E36F, +} + +var ngrams_8859_1_sv = [64]uint32{ + 0x206174, 0x206176, 0x206465, 0x20656E, 0x2066F6, 0x206861, 0x206920, 0x20696E, 0x206B6F, 0x206D65, 0x206F63, 0x2070E5, 0x20736B, 0x20736F, 0x207374, 0x207469, + 0x207661, 0x207669, 0x20E472, 0x616465, 0x616E20, 0x616E64, 0x617220, 0x617474, 0x636820, 0x646520, 0x64656E, 0x646572, 0x646574, 0x656420, 0x656E20, 0x657220, + 0x657420, 0x66F672, 0x67656E, 0x696C6C, 0x696E67, 0x6B6120, 0x6C6C20, 0x6D6564, 0x6E2073, 0x6E6120, 0x6E6465, 0x6E6720, 0x6E6765, 0x6E696E, 0x6F6368, 0x6F6D20, + 0x6F6E20, 0x70E520, 0x722061, 0x722073, 0x726120, 0x736B61, 0x736F6D, 0x742073, 0x746120, 0x746520, 0x746572, 0x74696C, 0x747420, 0x766172, 0xE47220, 0xF67220, +} + +func newRecognizer_8859_1(language string, ngram *[64]uint32) *recognizerSingleByte { + return &recognizerSingleByte{ + charset: "ISO-8859-1", + hasC1ByteCharset: "windows-1252", + language: language, + charMap: &charMap_8859_1, + ngram: ngram, + } +} + +func newRecognizer_8859_1_en() *recognizerSingleByte { + return newRecognizer_8859_1("en", &ngrams_8859_1_en) +} +func newRecognizer_8859_1_da() *recognizerSingleByte { + return newRecognizer_8859_1("da", &ngrams_8859_1_da) +} +func newRecognizer_8859_1_de() *recognizerSingleByte { + return newRecognizer_8859_1("de", &ngrams_8859_1_de) +} +func newRecognizer_8859_1_es() *recognizerSingleByte { + return newRecognizer_8859_1("es", &ngrams_8859_1_es) +} +func newRecognizer_8859_1_fr() *recognizerSingleByte { + return newRecognizer_8859_1("fr", &ngrams_8859_1_fr) +} +func newRecognizer_8859_1_it() *recognizerSingleByte { + return newRecognizer_8859_1("it", &ngrams_8859_1_it) +} +func newRecognizer_8859_1_nl() *recognizerSingleByte { + return newRecognizer_8859_1("nl", &ngrams_8859_1_nl) +} +func newRecognizer_8859_1_no() *recognizerSingleByte { + return newRecognizer_8859_1("no", &ngrams_8859_1_no) +} +func newRecognizer_8859_1_pt() *recognizerSingleByte { + return newRecognizer_8859_1("pt", &ngrams_8859_1_pt) +} +func newRecognizer_8859_1_sv() *recognizerSingleByte { + return newRecognizer_8859_1("sv", &ngrams_8859_1_sv) +} + +var charMap_8859_2 = [256]byte{ + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0xB1, 0x20, 0xB3, 0x20, 0xB5, 0xB6, 0x20, + 0x20, 0xB9, 0xBA, 0xBB, 0xBC, 0x20, 0xBE, 0xBF, + 0x20, 0xB1, 0x20, 0xB3, 0x20, 0xB5, 0xB6, 0xB7, + 0x20, 0xB9, 0xBA, 0xBB, 0xBC, 0x20, 0xBE, 0xBF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0x20, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0x20, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0x20, +} + +var ngrams_8859_2_cs = [64]uint32{ + 0x206120, 0x206279, 0x20646F, 0x206A65, 0x206E61, 0x206E65, 0x206F20, 0x206F64, 0x20706F, 0x207072, 0x2070F8, 0x20726F, 0x207365, 0x20736F, 0x207374, 0x20746F, + 0x207620, 0x207679, 0x207A61, 0x612070, 0x636520, 0x636820, 0x652070, 0x652073, 0x652076, 0x656D20, 0x656EED, 0x686F20, 0x686F64, 0x697374, 0x6A6520, 0x6B7465, + 0x6C6520, 0x6C6920, 0x6E6120, 0x6EE920, 0x6EEC20, 0x6EED20, 0x6F2070, 0x6F646E, 0x6F6A69, 0x6F7374, 0x6F7520, 0x6F7661, 0x706F64, 0x706F6A, 0x70726F, 0x70F865, + 0x736520, 0x736F75, 0x737461, 0x737469, 0x73746E, 0x746572, 0x746EED, 0x746F20, 0x752070, 0xBE6520, 0xE16EED, 0xE9686F, 0xED2070, 0xED2073, 0xED6D20, 0xF86564, +} + +var ngrams_8859_2_hu = [64]uint32{ + 0x206120, 0x20617A, 0x206265, 0x206567, 0x20656C, 0x206665, 0x206861, 0x20686F, 0x206973, 0x206B65, 0x206B69, 0x206BF6, 0x206C65, 0x206D61, 0x206D65, 0x206D69, + 0x206E65, 0x20737A, 0x207465, 0x20E973, 0x612061, 0x61206B, 0x61206D, 0x612073, 0x616B20, 0x616E20, 0x617A20, 0x62616E, 0x62656E, 0x656779, 0x656B20, 0x656C20, + 0x656C65, 0x656D20, 0x656E20, 0x657265, 0x657420, 0x657465, 0x657474, 0x677920, 0x686F67, 0x696E74, 0x697320, 0x6B2061, 0x6BF67A, 0x6D6567, 0x6D696E, 0x6E2061, + 0x6E616B, 0x6E656B, 0x6E656D, 0x6E7420, 0x6F6779, 0x732061, 0x737A65, 0x737A74, 0x737AE1, 0x73E967, 0x742061, 0x747420, 0x74E173, 0x7A6572, 0xE16E20, 0xE97320, +} + +var ngrams_8859_2_pl = [64]uint32{ + 0x20637A, 0x20646F, 0x206920, 0x206A65, 0x206B6F, 0x206D61, 0x206D69, 0x206E61, 0x206E69, 0x206F64, 0x20706F, 0x207072, 0x207369, 0x207720, 0x207769, 0x207779, + 0x207A20, 0x207A61, 0x612070, 0x612077, 0x616E69, 0x636820, 0x637A65, 0x637A79, 0x646F20, 0x647A69, 0x652070, 0x652073, 0x652077, 0x65207A, 0x65676F, 0x656A20, + 0x656D20, 0x656E69, 0x676F20, 0x696120, 0x696520, 0x69656A, 0x6B6120, 0x6B6920, 0x6B6965, 0x6D6965, 0x6E6120, 0x6E6961, 0x6E6965, 0x6F2070, 0x6F7761, 0x6F7769, + 0x706F6C, 0x707261, 0x70726F, 0x70727A, 0x727A65, 0x727A79, 0x7369EA, 0x736B69, 0x737461, 0x776965, 0x796368, 0x796D20, 0x7A6520, 0x7A6965, 0x7A7920, 0xF37720, +} + +var ngrams_8859_2_ro = [64]uint32{ + 0x206120, 0x206163, 0x206361, 0x206365, 0x20636F, 0x206375, 0x206465, 0x206469, 0x206C61, 0x206D61, 0x207065, 0x207072, 0x207365, 0x2073E3, 0x20756E, 0x20BA69, + 0x20EE6E, 0x612063, 0x612064, 0x617265, 0x617420, 0x617465, 0x617520, 0x636172, 0x636F6E, 0x637520, 0x63E320, 0x646520, 0x652061, 0x652063, 0x652064, 0x652070, + 0x652073, 0x656120, 0x656920, 0x656C65, 0x656E74, 0x657374, 0x692061, 0x692063, 0x692064, 0x692070, 0x696520, 0x696920, 0x696E20, 0x6C6120, 0x6C6520, 0x6C6F72, + 0x6C7569, 0x6E6520, 0x6E7472, 0x6F7220, 0x70656E, 0x726520, 0x726561, 0x727520, 0x73E320, 0x746520, 0x747275, 0x74E320, 0x756920, 0x756C20, 0xBA6920, 0xEE6E20, +} + +func newRecognizer_8859_2(language string, ngram *[64]uint32) *recognizerSingleByte { + return &recognizerSingleByte{ + charset: "ISO-8859-2", + hasC1ByteCharset: "windows-1250", + language: language, + charMap: &charMap_8859_2, + ngram: ngram, + } +} + +func newRecognizer_8859_2_cs() *recognizerSingleByte { + return newRecognizer_8859_1("cs", &ngrams_8859_2_cs) +} +func newRecognizer_8859_2_hu() *recognizerSingleByte { + return newRecognizer_8859_1("hu", &ngrams_8859_2_hu) +} +func newRecognizer_8859_2_pl() *recognizerSingleByte { + return newRecognizer_8859_1("pl", &ngrams_8859_2_pl) +} +func newRecognizer_8859_2_ro() *recognizerSingleByte { + return newRecognizer_8859_1("ro", &ngrams_8859_2_ro) +} + +var charMap_8859_5 = [256]byte{ + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0x20, 0xFE, 0xFF, + 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, + 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, + 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0x20, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0x20, 0xFE, 0xFF, +} + +var ngrams_8859_5_ru = [64]uint32{ + 0x20D220, 0x20D2DE, 0x20D4DE, 0x20D7D0, 0x20D820, 0x20DAD0, 0x20DADE, 0x20DDD0, 0x20DDD5, 0x20DED1, 0x20DFDE, 0x20DFE0, 0x20E0D0, 0x20E1DE, 0x20E1E2, 0x20E2DE, + 0x20E7E2, 0x20EDE2, 0xD0DDD8, 0xD0E2EC, 0xD3DE20, 0xD5DBEC, 0xD5DDD8, 0xD5E1E2, 0xD5E220, 0xD820DF, 0xD8D520, 0xD8D820, 0xD8EF20, 0xDBD5DD, 0xDBD820, 0xDBECDD, + 0xDDD020, 0xDDD520, 0xDDD8D5, 0xDDD8EF, 0xDDDE20, 0xDDDED2, 0xDE20D2, 0xDE20DF, 0xDE20E1, 0xDED220, 0xDED2D0, 0xDED3DE, 0xDED920, 0xDEDBEC, 0xDEDC20, 0xDEE1E2, + 0xDFDEDB, 0xDFE0D5, 0xDFE0D8, 0xDFE0DE, 0xE0D0D2, 0xE0D5D4, 0xE1E2D0, 0xE1E2D2, 0xE1E2D8, 0xE1EF20, 0xE2D5DB, 0xE2DE20, 0xE2DEE0, 0xE2EC20, 0xE7E2DE, 0xEBE520, +} + +func newRecognizer_8859_5(language string, ngram *[64]uint32) *recognizerSingleByte { + return &recognizerSingleByte{ + charset: "ISO-8859-5", + language: language, + charMap: &charMap_8859_5, + ngram: ngram, + } +} + +func newRecognizer_8859_5_ru() *recognizerSingleByte { + return newRecognizer_8859_5("ru", &ngrams_8859_5_ru) +} + +var charMap_8859_6 = [256]byte{ + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, + 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, + 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, + 0xD8, 0xD9, 0xDA, 0x20, 0x20, 0x20, 0x20, 0x20, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +} + +var ngrams_8859_6_ar = [64]uint32{ + 0x20C7E4, 0x20C7E6, 0x20C8C7, 0x20D9E4, 0x20E1EA, 0x20E4E4, 0x20E5E6, 0x20E8C7, 0xC720C7, 0xC7C120, 0xC7CA20, 0xC7D120, 0xC7E420, 0xC7E4C3, 0xC7E4C7, 0xC7E4C8, + 0xC7E4CA, 0xC7E4CC, 0xC7E4CD, 0xC7E4CF, 0xC7E4D3, 0xC7E4D9, 0xC7E4E2, 0xC7E4E5, 0xC7E4E8, 0xC7E4EA, 0xC7E520, 0xC7E620, 0xC7E6CA, 0xC820C7, 0xC920C7, 0xC920E1, + 0xC920E4, 0xC920E5, 0xC920E8, 0xCA20C7, 0xCF20C7, 0xCFC920, 0xD120C7, 0xD1C920, 0xD320C7, 0xD920C7, 0xD9E4E9, 0xE1EA20, 0xE420C7, 0xE4C920, 0xE4E920, 0xE4EA20, + 0xE520C7, 0xE5C720, 0xE5C920, 0xE5E620, 0xE620C7, 0xE720C7, 0xE7C720, 0xE8C7E4, 0xE8E620, 0xE920C7, 0xEA20C7, 0xEA20E5, 0xEA20E8, 0xEAC920, 0xEAD120, 0xEAE620, +} + +func newRecognizer_8859_6(language string, ngram *[64]uint32) *recognizerSingleByte { + return &recognizerSingleByte{ + charset: "ISO-8859-6", + language: language, + charMap: &charMap_8859_6, + ngram: ngram, + } +} + +func newRecognizer_8859_6_ar() *recognizerSingleByte { + return newRecognizer_8859_6("ar", &ngrams_8859_6_ar) +} + +var charMap_8859_7 = [256]byte{ + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0xA1, 0xA2, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xDC, 0x20, + 0xDD, 0xDE, 0xDF, 0x20, 0xFC, 0x20, 0xFD, 0xFE, + 0xC0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0x20, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xDC, 0xDD, 0xDE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0x20, +} + +var ngrams_8859_7_el = [64]uint32{ + 0x20E1ED, 0x20E1F0, 0x20E3E9, 0x20E4E9, 0x20E5F0, 0x20E720, 0x20EAE1, 0x20ECE5, 0x20EDE1, 0x20EF20, 0x20F0E1, 0x20F0EF, 0x20F0F1, 0x20F3F4, 0x20F3F5, 0x20F4E7, + 0x20F4EF, 0xDFE120, 0xE120E1, 0xE120F4, 0xE1E920, 0xE1ED20, 0xE1F0FC, 0xE1F220, 0xE3E9E1, 0xE5E920, 0xE5F220, 0xE720F4, 0xE7ED20, 0xE7F220, 0xE920F4, 0xE9E120, + 0xE9EADE, 0xE9F220, 0xEAE1E9, 0xEAE1F4, 0xECE520, 0xED20E1, 0xED20E5, 0xED20F0, 0xEDE120, 0xEFF220, 0xEFF520, 0xF0EFF5, 0xF0F1EF, 0xF0FC20, 0xF220E1, 0xF220E5, + 0xF220EA, 0xF220F0, 0xF220F4, 0xF3E520, 0xF3E720, 0xF3F4EF, 0xF4E120, 0xF4E1E9, 0xF4E7ED, 0xF4E7F2, 0xF4E9EA, 0xF4EF20, 0xF4EFF5, 0xF4F9ED, 0xF9ED20, 0xFEED20, +} + +func newRecognizer_8859_7(language string, ngram *[64]uint32) *recognizerSingleByte { + return &recognizerSingleByte{ + charset: "ISO-8859-7", + hasC1ByteCharset: "windows-1253", + language: language, + charMap: &charMap_8859_7, + ngram: ngram, + } +} + +func newRecognizer_8859_7_el() *recognizerSingleByte { + return newRecognizer_8859_7("el", &ngrams_8859_7_el) +} + +var charMap_8859_8 = [256]byte{ + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0xB5, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0x20, 0x20, 0x20, 0x20, 0x20, +} + +var ngrams_8859_8_I_he = [64]uint32{ + 0x20E0E5, 0x20E0E7, 0x20E0E9, 0x20E0FA, 0x20E1E9, 0x20E1EE, 0x20E4E0, 0x20E4E5, 0x20E4E9, 0x20E4EE, 0x20E4F2, 0x20E4F9, 0x20E4FA, 0x20ECE0, 0x20ECE4, 0x20EEE0, + 0x20F2EC, 0x20F9EC, 0xE0FA20, 0xE420E0, 0xE420E1, 0xE420E4, 0xE420EC, 0xE420EE, 0xE420F9, 0xE4E5E0, 0xE5E020, 0xE5ED20, 0xE5EF20, 0xE5F820, 0xE5FA20, 0xE920E4, + 0xE9E420, 0xE9E5FA, 0xE9E9ED, 0xE9ED20, 0xE9EF20, 0xE9F820, 0xE9FA20, 0xEC20E0, 0xEC20E4, 0xECE020, 0xECE420, 0xED20E0, 0xED20E1, 0xED20E4, 0xED20EC, 0xED20EE, + 0xED20F9, 0xEEE420, 0xEF20E4, 0xF0E420, 0xF0E920, 0xF0E9ED, 0xF2EC20, 0xF820E4, 0xF8E9ED, 0xF9EC20, 0xFA20E0, 0xFA20E1, 0xFA20E4, 0xFA20EC, 0xFA20EE, 0xFA20F9, +} + +var ngrams_8859_8_he = [64]uint32{ + 0x20E0E5, 0x20E0EC, 0x20E4E9, 0x20E4EC, 0x20E4EE, 0x20E4F0, 0x20E9F0, 0x20ECF2, 0x20ECF9, 0x20EDE5, 0x20EDE9, 0x20EFE5, 0x20EFE9, 0x20F8E5, 0x20F8E9, 0x20FAE0, + 0x20FAE5, 0x20FAE9, 0xE020E4, 0xE020EC, 0xE020ED, 0xE020FA, 0xE0E420, 0xE0E5E4, 0xE0EC20, 0xE0EE20, 0xE120E4, 0xE120ED, 0xE120FA, 0xE420E4, 0xE420E9, 0xE420EC, + 0xE420ED, 0xE420EF, 0xE420F8, 0xE420FA, 0xE4EC20, 0xE5E020, 0xE5E420, 0xE7E020, 0xE9E020, 0xE9E120, 0xE9E420, 0xEC20E4, 0xEC20ED, 0xEC20FA, 0xECF220, 0xECF920, + 0xEDE9E9, 0xEDE9F0, 0xEDE9F8, 0xEE20E4, 0xEE20ED, 0xEE20FA, 0xEEE120, 0xEEE420, 0xF2E420, 0xF920E4, 0xF920ED, 0xF920FA, 0xF9E420, 0xFAE020, 0xFAE420, 0xFAE5E9, +} + +func newRecognizer_8859_8(language string, ngram *[64]uint32) *recognizerSingleByte { + return &recognizerSingleByte{ + charset: "ISO-8859-8", + hasC1ByteCharset: "windows-1255", + language: language, + charMap: &charMap_8859_8, + ngram: ngram, + } +} + +func newRecognizer_8859_8_I_he() *recognizerSingleByte { + r := newRecognizer_8859_8("he", &ngrams_8859_8_I_he) + r.charset = "ISO-8859-8-I" + return r +} + +func newRecognizer_8859_8_he() *recognizerSingleByte { + return newRecognizer_8859_8("he", &ngrams_8859_8_he) +} + +var charMap_8859_9 = [256]byte{ + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0xAA, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0xB5, 0x20, 0x20, + 0x20, 0x20, 0xBA, 0x20, 0x20, 0x20, 0x20, 0x20, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0x20, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0x69, 0xFE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0x20, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, +} + +var ngrams_8859_9_tr = [64]uint32{ + 0x206261, 0x206269, 0x206275, 0x206461, 0x206465, 0x206765, 0x206861, 0x20696C, 0x206B61, 0x206B6F, 0x206D61, 0x206F6C, 0x207361, 0x207461, 0x207665, 0x207961, + 0x612062, 0x616B20, 0x616C61, 0x616D61, 0x616E20, 0x616EFD, 0x617220, 0x617261, 0x6172FD, 0x6173FD, 0x617961, 0x626972, 0x646120, 0x646520, 0x646920, 0x652062, + 0x65206B, 0x656469, 0x656E20, 0x657220, 0x657269, 0x657369, 0x696C65, 0x696E20, 0x696E69, 0x697220, 0x6C616E, 0x6C6172, 0x6C6520, 0x6C6572, 0x6E2061, 0x6E2062, + 0x6E206B, 0x6E6461, 0x6E6465, 0x6E6520, 0x6E6920, 0x6E696E, 0x6EFD20, 0x72696E, 0x72FD6E, 0x766520, 0x796120, 0x796F72, 0xFD6E20, 0xFD6E64, 0xFD6EFD, 0xFDF0FD, +} + +func newRecognizer_8859_9(language string, ngram *[64]uint32) *recognizerSingleByte { + return &recognizerSingleByte{ + charset: "ISO-8859-9", + hasC1ByteCharset: "windows-1254", + language: language, + charMap: &charMap_8859_9, + ngram: ngram, + } +} + +func newRecognizer_8859_9_tr() *recognizerSingleByte { + return newRecognizer_8859_9("tr", &ngrams_8859_9_tr) +} + +var charMap_windows_1256 = [256]byte{ + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x81, 0x20, 0x83, 0x20, 0x20, 0x20, 0x20, + 0x88, 0x20, 0x8A, 0x20, 0x9C, 0x8D, 0x8E, 0x8F, + 0x90, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x98, 0x20, 0x9A, 0x20, 0x9C, 0x20, 0x20, 0x9F, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0xAA, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0xB5, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, + 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, + 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0x20, + 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0x20, 0x20, 0x20, 0x20, 0xF4, 0x20, 0x20, 0x20, + 0x20, 0xF9, 0x20, 0xFB, 0xFC, 0x20, 0x20, 0xFF, +} + +var ngrams_windows_1256 = [64]uint32{ + 0x20C7E1, 0x20C7E4, 0x20C8C7, 0x20DAE1, 0x20DDED, 0x20E1E1, 0x20E3E4, 0x20E6C7, 0xC720C7, 0xC7C120, 0xC7CA20, 0xC7D120, 0xC7E120, 0xC7E1C3, 0xC7E1C7, 0xC7E1C8, + 0xC7E1CA, 0xC7E1CC, 0xC7E1CD, 0xC7E1CF, 0xC7E1D3, 0xC7E1DA, 0xC7E1DE, 0xC7E1E3, 0xC7E1E6, 0xC7E1ED, 0xC7E320, 0xC7E420, 0xC7E4CA, 0xC820C7, 0xC920C7, 0xC920DD, + 0xC920E1, 0xC920E3, 0xC920E6, 0xCA20C7, 0xCF20C7, 0xCFC920, 0xD120C7, 0xD1C920, 0xD320C7, 0xDA20C7, 0xDAE1EC, 0xDDED20, 0xE120C7, 0xE1C920, 0xE1EC20, 0xE1ED20, + 0xE320C7, 0xE3C720, 0xE3C920, 0xE3E420, 0xE420C7, 0xE520C7, 0xE5C720, 0xE6C7E1, 0xE6E420, 0xEC20C7, 0xED20C7, 0xED20E3, 0xED20E6, 0xEDC920, 0xEDD120, 0xEDE420, +} + +func newRecognizer_windows_1256() *recognizerSingleByte { + return &recognizerSingleByte{ + charset: "windows-1256", + language: "ar", + charMap: &charMap_windows_1256, + ngram: &ngrams_windows_1256, + } +} + +var charMap_windows_1251 = [256]byte{ + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x90, 0x83, 0x20, 0x83, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x9A, 0x20, 0x9C, 0x9D, 0x9E, 0x9F, + 0x90, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x9A, 0x20, 0x9C, 0x9D, 0x9E, 0x9F, + 0x20, 0xA2, 0xA2, 0xBC, 0x20, 0xB4, 0x20, 0x20, + 0xB8, 0x20, 0xBA, 0x20, 0x20, 0x20, 0x20, 0xBF, + 0x20, 0x20, 0xB3, 0xB3, 0xB4, 0xB5, 0x20, 0x20, + 0xB8, 0x20, 0xBA, 0x20, 0xBC, 0xBE, 0xBE, 0xBF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, +} + +var ngrams_windows_1251 = [64]uint32{ + 0x20E220, 0x20E2EE, 0x20E4EE, 0x20E7E0, 0x20E820, 0x20EAE0, 0x20EAEE, 0x20EDE0, 0x20EDE5, 0x20EEE1, 0x20EFEE, 0x20EFF0, 0x20F0E0, 0x20F1EE, 0x20F1F2, 0x20F2EE, + 0x20F7F2, 0x20FDF2, 0xE0EDE8, 0xE0F2FC, 0xE3EE20, 0xE5EBFC, 0xE5EDE8, 0xE5F1F2, 0xE5F220, 0xE820EF, 0xE8E520, 0xE8E820, 0xE8FF20, 0xEBE5ED, 0xEBE820, 0xEBFCED, + 0xEDE020, 0xEDE520, 0xEDE8E5, 0xEDE8FF, 0xEDEE20, 0xEDEEE2, 0xEE20E2, 0xEE20EF, 0xEE20F1, 0xEEE220, 0xEEE2E0, 0xEEE3EE, 0xEEE920, 0xEEEBFC, 0xEEEC20, 0xEEF1F2, + 0xEFEEEB, 0xEFF0E5, 0xEFF0E8, 0xEFF0EE, 0xF0E0E2, 0xF0E5E4, 0xF1F2E0, 0xF1F2E2, 0xF1F2E8, 0xF1FF20, 0xF2E5EB, 0xF2EE20, 0xF2EEF0, 0xF2FC20, 0xF7F2EE, 0xFBF520, +} + +func newRecognizer_windows_1251() *recognizerSingleByte { + return &recognizerSingleByte{ + charset: "windows-1251", + language: "ar", + charMap: &charMap_windows_1251, + ngram: &ngrams_windows_1251, + } +} + +var charMap_KOI8_R = [256]byte{ + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0xA3, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0xA3, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, + 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, + 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, + 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, + 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, + 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, + 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, +} + +var ngrams_KOI8_R = [64]uint32{ + 0x20C4CF, 0x20C920, 0x20CBC1, 0x20CBCF, 0x20CEC1, 0x20CEC5, 0x20CFC2, 0x20D0CF, 0x20D0D2, 0x20D2C1, 0x20D3CF, 0x20D3D4, 0x20D4CF, 0x20D720, 0x20D7CF, 0x20DAC1, + 0x20DCD4, 0x20DED4, 0xC1CEC9, 0xC1D4D8, 0xC5CCD8, 0xC5CEC9, 0xC5D3D4, 0xC5D420, 0xC7CF20, 0xC920D0, 0xC9C520, 0xC9C920, 0xC9D120, 0xCCC5CE, 0xCCC920, 0xCCD8CE, + 0xCEC120, 0xCEC520, 0xCEC9C5, 0xCEC9D1, 0xCECF20, 0xCECFD7, 0xCF20D0, 0xCF20D3, 0xCF20D7, 0xCFC7CF, 0xCFCA20, 0xCFCCD8, 0xCFCD20, 0xCFD3D4, 0xCFD720, 0xCFD7C1, + 0xD0CFCC, 0xD0D2C5, 0xD0D2C9, 0xD0D2CF, 0xD2C1D7, 0xD2C5C4, 0xD3D120, 0xD3D4C1, 0xD3D4C9, 0xD3D4D7, 0xD4C5CC, 0xD4CF20, 0xD4CFD2, 0xD4D820, 0xD9C820, 0xDED4CF, +} + +func newRecognizer_KOI8_R() *recognizerSingleByte { + return &recognizerSingleByte{ + charset: "KOI8-R", + language: "ru", + charMap: &charMap_KOI8_R, + ngram: &ngrams_KOI8_R, + } +} + +var charMap_IBM424_he = [256]byte{ + /* -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -A -B -C -D -E -F */ + /* 0- */ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + /* 1- */ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + /* 2- */ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + /* 3- */ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + /* 4- */ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + /* 5- */ 0x40, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + /* 6- */ 0x40, 0x40, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + /* 7- */ 0x40, 0x71, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x40, 0x40, + /* 8- */ 0x40, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + /* 9- */ 0x40, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + /* A- */ 0xA0, 0x40, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + /* B- */ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + /* C- */ 0x40, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + /* D- */ 0x40, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + /* E- */ 0x40, 0x40, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + /* F- */ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, +} + +var ngrams_IBM424_he_rtl = [64]uint32{ + 0x404146, 0x404148, 0x404151, 0x404171, 0x404251, 0x404256, 0x404541, 0x404546, 0x404551, 0x404556, 0x404562, 0x404569, 0x404571, 0x405441, 0x405445, 0x405641, + 0x406254, 0x406954, 0x417140, 0x454041, 0x454042, 0x454045, 0x454054, 0x454056, 0x454069, 0x454641, 0x464140, 0x465540, 0x465740, 0x466840, 0x467140, 0x514045, + 0x514540, 0x514671, 0x515155, 0x515540, 0x515740, 0x516840, 0x517140, 0x544041, 0x544045, 0x544140, 0x544540, 0x554041, 0x554042, 0x554045, 0x554054, 0x554056, + 0x554069, 0x564540, 0x574045, 0x584540, 0x585140, 0x585155, 0x625440, 0x684045, 0x685155, 0x695440, 0x714041, 0x714042, 0x714045, 0x714054, 0x714056, 0x714069, +} + +var ngrams_IBM424_he_ltr = [64]uint32{ + 0x404146, 0x404154, 0x404551, 0x404554, 0x404556, 0x404558, 0x405158, 0x405462, 0x405469, 0x405546, 0x405551, 0x405746, 0x405751, 0x406846, 0x406851, 0x407141, + 0x407146, 0x407151, 0x414045, 0x414054, 0x414055, 0x414071, 0x414540, 0x414645, 0x415440, 0x415640, 0x424045, 0x424055, 0x424071, 0x454045, 0x454051, 0x454054, + 0x454055, 0x454057, 0x454068, 0x454071, 0x455440, 0x464140, 0x464540, 0x484140, 0x514140, 0x514240, 0x514540, 0x544045, 0x544055, 0x544071, 0x546240, 0x546940, + 0x555151, 0x555158, 0x555168, 0x564045, 0x564055, 0x564071, 0x564240, 0x564540, 0x624540, 0x694045, 0x694055, 0x694071, 0x694540, 0x714140, 0x714540, 0x714651, +} + +func newRecognizer_IBM424_he(charset string, ngram *[64]uint32) *recognizerSingleByte { + return &recognizerSingleByte{ + charset: charset, + language: "he", + charMap: &charMap_IBM424_he, + ngram: ngram, + } +} + +func newRecognizer_IBM424_he_rtl() *recognizerSingleByte { + return newRecognizer_IBM424_he("IBM424_rtl", &ngrams_IBM424_he_rtl) +} + +func newRecognizer_IBM424_he_ltr() *recognizerSingleByte { + return newRecognizer_IBM424_he("IBM424_ltr", &ngrams_IBM424_he_ltr) +} + +var charMap_IBM420_ar = [256]byte{ + /* -0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -A -B -C -D -E -F */ + /* 0- */ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + /* 1- */ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + /* 2- */ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + /* 3- */ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + /* 4- */ 0x40, 0x40, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + /* 5- */ 0x40, 0x51, 0x52, 0x40, 0x40, 0x55, 0x56, 0x57, 0x58, 0x59, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + /* 6- */ 0x40, 0x40, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + /* 7- */ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + /* 8- */ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, + /* 9- */ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, + /* A- */ 0xA0, 0x40, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, + /* B- */ 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0x40, 0x40, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, + /* C- */ 0x40, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x40, 0xCB, 0x40, 0xCD, 0x40, 0xCF, + /* D- */ 0x40, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, + /* E- */ 0x40, 0x40, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xEA, 0xEB, 0x40, 0xED, 0xEE, 0xEF, + /* F- */ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xFB, 0xFC, 0xFD, 0xFE, 0x40, +} + +var ngrams_IBM420_ar_rtl = [64]uint32{ + 0x4056B1, 0x4056BD, 0x405856, 0x409AB1, 0x40ABDC, 0x40B1B1, 0x40BBBD, 0x40CF56, 0x564056, 0x564640, 0x566340, 0x567540, 0x56B140, 0x56B149, 0x56B156, 0x56B158, + 0x56B163, 0x56B167, 0x56B169, 0x56B173, 0x56B178, 0x56B19A, 0x56B1AD, 0x56B1BB, 0x56B1CF, 0x56B1DC, 0x56BB40, 0x56BD40, 0x56BD63, 0x584056, 0x624056, 0x6240AB, + 0x6240B1, 0x6240BB, 0x6240CF, 0x634056, 0x734056, 0x736240, 0x754056, 0x756240, 0x784056, 0x9A4056, 0x9AB1DA, 0xABDC40, 0xB14056, 0xB16240, 0xB1DA40, 0xB1DC40, + 0xBB4056, 0xBB5640, 0xBB6240, 0xBBBD40, 0xBD4056, 0xBF4056, 0xBF5640, 0xCF56B1, 0xCFBD40, 0xDA4056, 0xDC4056, 0xDC40BB, 0xDC40CF, 0xDC6240, 0xDC7540, 0xDCBD40, +} + +var ngrams_IBM420_ar_ltr = [64]uint32{ + 0x404656, 0x4056BB, 0x4056BF, 0x406273, 0x406275, 0x4062B1, 0x4062BB, 0x4062DC, 0x406356, 0x407556, 0x4075DC, 0x40B156, 0x40BB56, 0x40BD56, 0x40BDBB, 0x40BDCF, + 0x40BDDC, 0x40DAB1, 0x40DCAB, 0x40DCB1, 0x49B156, 0x564056, 0x564058, 0x564062, 0x564063, 0x564073, 0x564075, 0x564078, 0x56409A, 0x5640B1, 0x5640BB, 0x5640BD, + 0x5640BF, 0x5640DA, 0x5640DC, 0x565840, 0x56B156, 0x56CF40, 0x58B156, 0x63B156, 0x63BD56, 0x67B156, 0x69B156, 0x73B156, 0x78B156, 0x9AB156, 0xAB4062, 0xADB156, + 0xB14062, 0xB15640, 0xB156CF, 0xB19A40, 0xB1B140, 0xBB4062, 0xBB40DC, 0xBBB156, 0xBD5640, 0xBDBB40, 0xCF4062, 0xCF40DC, 0xCFB156, 0xDAB19A, 0xDCAB40, 0xDCB156, +} + +func newRecognizer_IBM420_ar(charset string, ngram *[64]uint32) *recognizerSingleByte { + return &recognizerSingleByte{ + charset: charset, + language: "ar", + charMap: &charMap_IBM420_ar, + ngram: ngram, + } +} + +func newRecognizer_IBM420_ar_rtl() *recognizerSingleByte { + return newRecognizer_IBM420_ar("IBM420_rtl", &ngrams_IBM420_ar_rtl) +} + +func newRecognizer_IBM420_ar_ltr() *recognizerSingleByte { + return newRecognizer_IBM420_ar("IBM420_ltr", &ngrams_IBM420_ar_ltr) +} diff --git a/vendor/github.com/saintfish/chardet/unicode.go b/vendor/github.com/saintfish/chardet/unicode.go new file mode 100644 index 00000000..6f9fa9e6 --- /dev/null +++ b/vendor/github.com/saintfish/chardet/unicode.go @@ -0,0 +1,103 @@ +package chardet + +import ( + "bytes" +) + +var ( + utf16beBom = []byte{0xFE, 0xFF} + utf16leBom = []byte{0xFF, 0xFE} + utf32beBom = []byte{0x00, 0x00, 0xFE, 0xFF} + utf32leBom = []byte{0xFF, 0xFE, 0x00, 0x00} +) + +type recognizerUtf16be struct { +} + +func newRecognizer_utf16be() *recognizerUtf16be { + return &recognizerUtf16be{} +} + +func (*recognizerUtf16be) Match(input *recognizerInput) (output recognizerOutput) { + output = recognizerOutput{ + Charset: "UTF-16BE", + } + if bytes.HasPrefix(input.raw, utf16beBom) { + output.Confidence = 100 + } + return +} + +type recognizerUtf16le struct { +} + +func newRecognizer_utf16le() *recognizerUtf16le { + return &recognizerUtf16le{} +} + +func (*recognizerUtf16le) Match(input *recognizerInput) (output recognizerOutput) { + output = recognizerOutput{ + Charset: "UTF-16LE", + } + if bytes.HasPrefix(input.raw, utf16leBom) && !bytes.HasPrefix(input.raw, utf32leBom) { + output.Confidence = 100 + } + return +} + +type recognizerUtf32 struct { + name string + bom []byte + decodeChar func(input []byte) uint32 +} + +func decodeUtf32be(input []byte) uint32 { + return uint32(input[0])<<24 | uint32(input[1])<<16 | uint32(input[2])<<8 | uint32(input[3]) +} + +func decodeUtf32le(input []byte) uint32 { + return uint32(input[3])<<24 | uint32(input[2])<<16 | uint32(input[1])<<8 | uint32(input[0]) +} + +func newRecognizer_utf32be() *recognizerUtf32 { + return &recognizerUtf32{ + "UTF-32BE", + utf32beBom, + decodeUtf32be, + } +} + +func newRecognizer_utf32le() *recognizerUtf32 { + return &recognizerUtf32{ + "UTF-32LE", + utf32leBom, + decodeUtf32le, + } +} + +func (r *recognizerUtf32) Match(input *recognizerInput) (output recognizerOutput) { + output = recognizerOutput{ + Charset: r.name, + } + hasBom := bytes.HasPrefix(input.raw, r.bom) + var numValid, numInvalid uint32 + for b := input.raw; len(b) >= 4; b = b[4:] { + if c := r.decodeChar(b); c >= 0x10FFFF || (c >= 0xD800 && c <= 0xDFFF) { + numInvalid++ + } else { + numValid++ + } + } + if hasBom && numInvalid == 0 { + output.Confidence = 100 + } else if hasBom && numValid > numInvalid*10 { + output.Confidence = 80 + } else if numValid > 3 && numInvalid == 0 { + output.Confidence = 100 + } else if numValid > 0 && numInvalid == 0 { + output.Confidence = 80 + } else if numValid > numInvalid*10 { + output.Confidence = 25 + } + return +} diff --git a/vendor/github.com/saintfish/chardet/utf8.go b/vendor/github.com/saintfish/chardet/utf8.go new file mode 100644 index 00000000..ae036ad9 --- /dev/null +++ b/vendor/github.com/saintfish/chardet/utf8.go @@ -0,0 +1,71 @@ +package chardet + +import ( + "bytes" +) + +var utf8Bom = []byte{0xEF, 0xBB, 0xBF} + +type recognizerUtf8 struct { +} + +func newRecognizer_utf8() *recognizerUtf8 { + return &recognizerUtf8{} +} + +func (*recognizerUtf8) Match(input *recognizerInput) (output recognizerOutput) { + output = recognizerOutput{ + Charset: "UTF-8", + } + hasBom := bytes.HasPrefix(input.raw, utf8Bom) + inputLen := len(input.raw) + var numValid, numInvalid uint32 + var trailBytes uint8 + for i := 0; i < inputLen; i++ { + c := input.raw[i] + if c&0x80 == 0 { + continue + } + if c&0xE0 == 0xC0 { + trailBytes = 1 + } else if c&0xF0 == 0xE0 { + trailBytes = 2 + } else if c&0xF8 == 0xF0 { + trailBytes = 3 + } else { + numInvalid++ + if numInvalid > 5 { + break + } + trailBytes = 0 + } + + for i++; i < inputLen; i++ { + c = input.raw[i] + if c&0xC0 != 0x80 { + numInvalid++ + break + } + if trailBytes--; trailBytes == 0 { + numValid++ + break + } + } + } + + if hasBom && numInvalid == 0 { + output.Confidence = 100 + } else if hasBom && numValid > numInvalid*10 { + output.Confidence = 80 + } else if numValid > 3 && numInvalid == 0 { + output.Confidence = 100 + } else if numValid > 0 && numInvalid == 0 { + output.Confidence = 80 + } else if numValid == 0 && numInvalid == 0 { + // Plain ASCII + output.Confidence = 10 + } else if numValid > numInvalid*10 { + output.Confidence = 25 + } + return +} diff --git a/vendor/golang.org/x/image/bmp/reader.go b/vendor/golang.org/x/image/bmp/reader.go new file mode 100644 index 00000000..1939c112 --- /dev/null +++ b/vendor/golang.org/x/image/bmp/reader.go @@ -0,0 +1,253 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package bmp implements a BMP image decoder and encoder. +// +// The BMP specification is at http://www.digicamsoft.com/bmp/bmp.html. +package bmp // import "golang.org/x/image/bmp" + +import ( + "errors" + "image" + "image/color" + "io" +) + +// ErrUnsupported means that the input BMP image uses a valid but unsupported +// feature. +var ErrUnsupported = errors.New("bmp: unsupported BMP image") + +func readUint16(b []byte) uint16 { + return uint16(b[0]) | uint16(b[1])<<8 +} + +func readUint32(b []byte) uint32 { + return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 +} + +// decodePaletted reads an 8 bit-per-pixel BMP image from r. +// If topDown is false, the image rows will be read bottom-up. +func decodePaletted(r io.Reader, c image.Config, topDown bool) (image.Image, error) { + paletted := image.NewPaletted(image.Rect(0, 0, c.Width, c.Height), c.ColorModel.(color.Palette)) + if c.Width == 0 || c.Height == 0 { + return paletted, nil + } + var tmp [4]byte + y0, y1, yDelta := c.Height-1, -1, -1 + if topDown { + y0, y1, yDelta = 0, c.Height, +1 + } + for y := y0; y != y1; y += yDelta { + p := paletted.Pix[y*paletted.Stride : y*paletted.Stride+c.Width] + if _, err := io.ReadFull(r, p); err != nil { + return nil, err + } + // Each row is 4-byte aligned. + if c.Width%4 != 0 { + _, err := io.ReadFull(r, tmp[:4-c.Width%4]) + if err != nil { + return nil, err + } + } + } + return paletted, nil +} + +// decodeRGB reads a 24 bit-per-pixel BMP image from r. +// If topDown is false, the image rows will be read bottom-up. +func decodeRGB(r io.Reader, c image.Config, topDown bool) (image.Image, error) { + rgba := image.NewRGBA(image.Rect(0, 0, c.Width, c.Height)) + if c.Width == 0 || c.Height == 0 { + return rgba, nil + } + // There are 3 bytes per pixel, and each row is 4-byte aligned. + b := make([]byte, (3*c.Width+3)&^3) + y0, y1, yDelta := c.Height-1, -1, -1 + if topDown { + y0, y1, yDelta = 0, c.Height, +1 + } + for y := y0; y != y1; y += yDelta { + if _, err := io.ReadFull(r, b); err != nil { + return nil, err + } + p := rgba.Pix[y*rgba.Stride : y*rgba.Stride+c.Width*4] + for i, j := 0, 0; i < len(p); i, j = i+4, j+3 { + // BMP images are stored in BGR order rather than RGB order. + p[i+0] = b[j+2] + p[i+1] = b[j+1] + p[i+2] = b[j+0] + p[i+3] = 0xFF + } + } + return rgba, nil +} + +// decodeNRGBA reads a 32 bit-per-pixel BMP image from r. +// If topDown is false, the image rows will be read bottom-up. +func decodeNRGBA(r io.Reader, c image.Config, topDown, allowAlpha bool) (image.Image, error) { + rgba := image.NewNRGBA(image.Rect(0, 0, c.Width, c.Height)) + if c.Width == 0 || c.Height == 0 { + return rgba, nil + } + y0, y1, yDelta := c.Height-1, -1, -1 + if topDown { + y0, y1, yDelta = 0, c.Height, +1 + } + for y := y0; y != y1; y += yDelta { + p := rgba.Pix[y*rgba.Stride : y*rgba.Stride+c.Width*4] + if _, err := io.ReadFull(r, p); err != nil { + return nil, err + } + for i := 0; i < len(p); i += 4 { + // BMP images are stored in BGRA order rather than RGBA order. + p[i+0], p[i+2] = p[i+2], p[i+0] + if !allowAlpha { + p[i+3] = 0xFF + } + } + } + return rgba, nil +} + +// Decode reads a BMP image from r and returns it as an image.Image. +// Limitation: The file must be 8, 24 or 32 bits per pixel. +func Decode(r io.Reader) (image.Image, error) { + c, bpp, topDown, allowAlpha, err := decodeConfig(r) + if err != nil { + return nil, err + } + switch bpp { + case 8: + return decodePaletted(r, c, topDown) + case 24: + return decodeRGB(r, c, topDown) + case 32: + return decodeNRGBA(r, c, topDown, allowAlpha) + } + panic("unreachable") +} + +// DecodeConfig returns the color model and dimensions of a BMP image without +// decoding the entire image. +// Limitation: The file must be 8, 24 or 32 bits per pixel. +func DecodeConfig(r io.Reader) (image.Config, error) { + config, _, _, _, err := decodeConfig(r) + return config, err +} + +func decodeConfig(r io.Reader) (config image.Config, bitsPerPixel int, topDown bool, allowAlpha bool, err error) { + // We only support those BMP images with one of the following DIB headers: + // - BITMAPINFOHEADER (40 bytes) + // - BITMAPV4HEADER (108 bytes) + // - BITMAPV5HEADER (124 bytes) + const ( + fileHeaderLen = 14 + infoHeaderLen = 40 + v4InfoHeaderLen = 108 + v5InfoHeaderLen = 124 + ) + var b [1024]byte + if _, err := io.ReadFull(r, b[:fileHeaderLen+4]); err != nil { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + return image.Config{}, 0, false, false, err + } + if string(b[:2]) != "BM" { + return image.Config{}, 0, false, false, errors.New("bmp: invalid format") + } + offset := readUint32(b[10:14]) + infoLen := readUint32(b[14:18]) + if infoLen != infoHeaderLen && infoLen != v4InfoHeaderLen && infoLen != v5InfoHeaderLen { + return image.Config{}, 0, false, false, ErrUnsupported + } + if _, err := io.ReadFull(r, b[fileHeaderLen+4:fileHeaderLen+infoLen]); err != nil { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + return image.Config{}, 0, false, false, err + } + width := int(int32(readUint32(b[18:22]))) + height := int(int32(readUint32(b[22:26]))) + if height < 0 { + height, topDown = -height, true + } + if width < 0 || height < 0 { + return image.Config{}, 0, false, false, ErrUnsupported + } + // We only support 1 plane and 8, 24 or 32 bits per pixel and no + // compression. + planes, bpp, compression := readUint16(b[26:28]), readUint16(b[28:30]), readUint32(b[30:34]) + // if compression is set to BI_BITFIELDS, but the bitmask is set to the default bitmask + // that would be used if compression was set to 0, we can continue as if compression was 0 + if compression == 3 && infoLen > infoHeaderLen && + readUint32(b[54:58]) == 0xff0000 && readUint32(b[58:62]) == 0xff00 && + readUint32(b[62:66]) == 0xff && readUint32(b[66:70]) == 0xff000000 { + compression = 0 + } + if planes != 1 || compression != 0 { + return image.Config{}, 0, false, false, ErrUnsupported + } + switch bpp { + case 8: + colorUsed := readUint32(b[46:50]) + // If colorUsed is 0, it is set to the maximum number of colors for the given bpp, which is 2^bpp. + if colorUsed == 0 { + colorUsed = 256 + } else if colorUsed > 256 { + return image.Config{}, 0, false, false, ErrUnsupported + } + + if offset != fileHeaderLen+infoLen+colorUsed*4 { + return image.Config{}, 0, false, false, ErrUnsupported + } + _, err = io.ReadFull(r, b[:colorUsed*4]) + if err != nil { + return image.Config{}, 0, false, false, err + } + pcm := make(color.Palette, colorUsed) + for i := range pcm { + // BMP images are stored in BGR order rather than RGB order. + // Every 4th byte is padding. + pcm[i] = color.RGBA{b[4*i+2], b[4*i+1], b[4*i+0], 0xFF} + } + return image.Config{ColorModel: pcm, Width: width, Height: height}, 8, topDown, false, nil + case 24: + if offset != fileHeaderLen+infoLen { + return image.Config{}, 0, false, false, ErrUnsupported + } + return image.Config{ColorModel: color.RGBAModel, Width: width, Height: height}, 24, topDown, false, nil + case 32: + if offset != fileHeaderLen+infoLen { + return image.Config{}, 0, false, false, ErrUnsupported + } + // 32 bits per pixel is possibly RGBX (X is padding) or RGBA (A is + // alpha transparency). However, for BMP images, "Alpha is a + // poorly-documented and inconsistently-used feature" says + // https://source.chromium.org/chromium/chromium/src/+/bc0a792d7ebc587190d1a62ccddba10abeea274b:third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_reader.cc;l=621 + // + // That goes on to say "BITMAPV3HEADER+ have an alpha bitmask in the + // info header... so we respect it at all times... [For earlier + // (smaller) headers we] ignore alpha in Windows V3 BMPs except inside + // ICO files". + // + // "Ignore" means to always set alpha to 0xFF (fully opaque): + // https://source.chromium.org/chromium/chromium/src/+/bc0a792d7ebc587190d1a62ccddba10abeea274b:third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_reader.h;l=272 + // + // Confusingly, "Windows V3" does not correspond to BITMAPV3HEADER, but + // instead corresponds to the earlier (smaller) BITMAPINFOHEADER: + // https://source.chromium.org/chromium/chromium/src/+/bc0a792d7ebc587190d1a62ccddba10abeea274b:third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_reader.cc;l=258 + // + // This Go package does not support ICO files and the (infoLen > + // infoHeaderLen) condition distinguishes BITMAPINFOHEADER (40 bytes) + // vs later (larger) headers. + allowAlpha = infoLen > infoHeaderLen + return image.Config{ColorModel: color.RGBAModel, Width: width, Height: height}, 32, topDown, allowAlpha, nil + } + return image.Config{}, 0, false, false, ErrUnsupported +} + +func init() { + image.RegisterFormat("bmp", "BM????\x00\x00\x00\x00", Decode, DecodeConfig) +} diff --git a/vendor/golang.org/x/image/bmp/writer.go b/vendor/golang.org/x/image/bmp/writer.go new file mode 100644 index 00000000..f07b39db --- /dev/null +++ b/vendor/golang.org/x/image/bmp/writer.go @@ -0,0 +1,262 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package bmp + +import ( + "encoding/binary" + "errors" + "image" + "io" +) + +type header struct { + sigBM [2]byte + fileSize uint32 + resverved [2]uint16 + pixOffset uint32 + dibHeaderSize uint32 + width uint32 + height uint32 + colorPlane uint16 + bpp uint16 + compression uint32 + imageSize uint32 + xPixelsPerMeter uint32 + yPixelsPerMeter uint32 + colorUse uint32 + colorImportant uint32 +} + +func encodePaletted(w io.Writer, pix []uint8, dx, dy, stride, step int) error { + var padding []byte + if dx < step { + padding = make([]byte, step-dx) + } + for y := dy - 1; y >= 0; y-- { + min := y*stride + 0 + max := y*stride + dx + if _, err := w.Write(pix[min:max]); err != nil { + return err + } + if padding != nil { + if _, err := w.Write(padding); err != nil { + return err + } + } + } + return nil +} + +func encodeRGBA(w io.Writer, pix []uint8, dx, dy, stride, step int, opaque bool) error { + buf := make([]byte, step) + if opaque { + for y := dy - 1; y >= 0; y-- { + min := y*stride + 0 + max := y*stride + dx*4 + off := 0 + for i := min; i < max; i += 4 { + buf[off+2] = pix[i+0] + buf[off+1] = pix[i+1] + buf[off+0] = pix[i+2] + off += 3 + } + if _, err := w.Write(buf); err != nil { + return err + } + } + } else { + for y := dy - 1; y >= 0; y-- { + min := y*stride + 0 + max := y*stride + dx*4 + off := 0 + for i := min; i < max; i += 4 { + a := uint32(pix[i+3]) + if a == 0 { + buf[off+2] = 0 + buf[off+1] = 0 + buf[off+0] = 0 + buf[off+3] = 0 + off += 4 + continue + } else if a == 0xff { + buf[off+2] = pix[i+0] + buf[off+1] = pix[i+1] + buf[off+0] = pix[i+2] + buf[off+3] = 0xff + off += 4 + continue + } + buf[off+2] = uint8(((uint32(pix[i+0]) * 0xffff) / a) >> 8) + buf[off+1] = uint8(((uint32(pix[i+1]) * 0xffff) / a) >> 8) + buf[off+0] = uint8(((uint32(pix[i+2]) * 0xffff) / a) >> 8) + buf[off+3] = uint8(a) + off += 4 + } + if _, err := w.Write(buf); err != nil { + return err + } + } + } + return nil +} + +func encodeNRGBA(w io.Writer, pix []uint8, dx, dy, stride, step int, opaque bool) error { + buf := make([]byte, step) + if opaque { + for y := dy - 1; y >= 0; y-- { + min := y*stride + 0 + max := y*stride + dx*4 + off := 0 + for i := min; i < max; i += 4 { + buf[off+2] = pix[i+0] + buf[off+1] = pix[i+1] + buf[off+0] = pix[i+2] + off += 3 + } + if _, err := w.Write(buf); err != nil { + return err + } + } + } else { + for y := dy - 1; y >= 0; y-- { + min := y*stride + 0 + max := y*stride + dx*4 + off := 0 + for i := min; i < max; i += 4 { + buf[off+2] = pix[i+0] + buf[off+1] = pix[i+1] + buf[off+0] = pix[i+2] + buf[off+3] = pix[i+3] + off += 4 + } + if _, err := w.Write(buf); err != nil { + return err + } + } + } + return nil +} + +func encode(w io.Writer, m image.Image, step int) error { + b := m.Bounds() + buf := make([]byte, step) + for y := b.Max.Y - 1; y >= b.Min.Y; y-- { + off := 0 + for x := b.Min.X; x < b.Max.X; x++ { + r, g, b, _ := m.At(x, y).RGBA() + buf[off+2] = byte(r >> 8) + buf[off+1] = byte(g >> 8) + buf[off+0] = byte(b >> 8) + off += 3 + } + if _, err := w.Write(buf); err != nil { + return err + } + } + return nil +} + +// Encode writes the image m to w in BMP format. +func Encode(w io.Writer, m image.Image) error { + d := m.Bounds().Size() + if d.X < 0 || d.Y < 0 { + return errors.New("bmp: negative bounds") + } + h := &header{ + sigBM: [2]byte{'B', 'M'}, + fileSize: 14 + 40, + pixOffset: 14 + 40, + dibHeaderSize: 40, + width: uint32(d.X), + height: uint32(d.Y), + colorPlane: 1, + } + + var step int + var palette []byte + var opaque bool + switch m := m.(type) { + case *image.Gray: + step = (d.X + 3) &^ 3 + palette = make([]byte, 1024) + for i := 0; i < 256; i++ { + palette[i*4+0] = uint8(i) + palette[i*4+1] = uint8(i) + palette[i*4+2] = uint8(i) + palette[i*4+3] = 0xFF + } + h.imageSize = uint32(d.Y * step) + h.fileSize += uint32(len(palette)) + h.imageSize + h.pixOffset += uint32(len(palette)) + h.bpp = 8 + + case *image.Paletted: + step = (d.X + 3) &^ 3 + palette = make([]byte, 1024) + for i := 0; i < len(m.Palette) && i < 256; i++ { + r, g, b, _ := m.Palette[i].RGBA() + palette[i*4+0] = uint8(b >> 8) + palette[i*4+1] = uint8(g >> 8) + palette[i*4+2] = uint8(r >> 8) + palette[i*4+3] = 0xFF + } + h.imageSize = uint32(d.Y * step) + h.fileSize += uint32(len(palette)) + h.imageSize + h.pixOffset += uint32(len(palette)) + h.bpp = 8 + case *image.RGBA: + opaque = m.Opaque() + if opaque { + step = (3*d.X + 3) &^ 3 + h.bpp = 24 + } else { + step = 4 * d.X + h.bpp = 32 + } + h.imageSize = uint32(d.Y * step) + h.fileSize += h.imageSize + case *image.NRGBA: + opaque = m.Opaque() + if opaque { + step = (3*d.X + 3) &^ 3 + h.bpp = 24 + } else { + step = 4 * d.X + h.bpp = 32 + } + h.imageSize = uint32(d.Y * step) + h.fileSize += h.imageSize + default: + step = (3*d.X + 3) &^ 3 + h.imageSize = uint32(d.Y * step) + h.fileSize += h.imageSize + h.bpp = 24 + } + + if err := binary.Write(w, binary.LittleEndian, h); err != nil { + return err + } + if palette != nil { + if err := binary.Write(w, binary.LittleEndian, palette); err != nil { + return err + } + } + + if d.X == 0 || d.Y == 0 { + return nil + } + + switch m := m.(type) { + case *image.Gray: + return encodePaletted(w, m.Pix, d.X, d.Y, m.Stride, step) + case *image.Paletted: + return encodePaletted(w, m.Pix, d.X, d.Y, m.Stride, step) + case *image.RGBA: + return encodeRGBA(w, m.Pix, d.X, d.Y, m.Stride, step, opaque) + case *image.NRGBA: + return encodeNRGBA(w, m.Pix, d.X, d.Y, m.Stride, step, opaque) + } + return encode(w, m, step) +} diff --git a/vendor/golang.org/x/text/encoding/charmap/charmap.go b/vendor/golang.org/x/text/encoding/charmap/charmap.go new file mode 100644 index 00000000..e89ff073 --- /dev/null +++ b/vendor/golang.org/x/text/encoding/charmap/charmap.go @@ -0,0 +1,249 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:generate go run maketables.go + +// Package charmap provides simple character encodings such as IBM Code Page 437 +// and Windows 1252. +package charmap // import "golang.org/x/text/encoding/charmap" + +import ( + "unicode/utf8" + + "golang.org/x/text/encoding" + "golang.org/x/text/encoding/internal" + "golang.org/x/text/encoding/internal/identifier" + "golang.org/x/text/transform" +) + +// These encodings vary only in the way clients should interpret them. Their +// coded character set is identical and a single implementation can be shared. +var ( + // ISO8859_6E is the ISO 8859-6E encoding. + ISO8859_6E encoding.Encoding = &iso8859_6E + + // ISO8859_6I is the ISO 8859-6I encoding. + ISO8859_6I encoding.Encoding = &iso8859_6I + + // ISO8859_8E is the ISO 8859-8E encoding. + ISO8859_8E encoding.Encoding = &iso8859_8E + + // ISO8859_8I is the ISO 8859-8I encoding. + ISO8859_8I encoding.Encoding = &iso8859_8I + + iso8859_6E = internal.Encoding{ + Encoding: ISO8859_6, + Name: "ISO-8859-6E", + MIB: identifier.ISO88596E, + } + + iso8859_6I = internal.Encoding{ + Encoding: ISO8859_6, + Name: "ISO-8859-6I", + MIB: identifier.ISO88596I, + } + + iso8859_8E = internal.Encoding{ + Encoding: ISO8859_8, + Name: "ISO-8859-8E", + MIB: identifier.ISO88598E, + } + + iso8859_8I = internal.Encoding{ + Encoding: ISO8859_8, + Name: "ISO-8859-8I", + MIB: identifier.ISO88598I, + } +) + +// All is a list of all defined encodings in this package. +var All []encoding.Encoding = listAll + +// TODO: implement these encodings, in order of importance. +// ASCII, ISO8859_1: Rather common. Close to Windows 1252. +// ISO8859_9: Close to Windows 1254. + +// utf8Enc holds a rune's UTF-8 encoding in data[:len]. +type utf8Enc struct { + len uint8 + data [3]byte +} + +// Charmap is an 8-bit character set encoding. +type Charmap struct { + // name is the encoding's name. + name string + // mib is the encoding type of this encoder. + mib identifier.MIB + // asciiSuperset states whether the encoding is a superset of ASCII. + asciiSuperset bool + // low is the lower bound of the encoded byte for a non-ASCII rune. If + // Charmap.asciiSuperset is true then this will be 0x80, otherwise 0x00. + low uint8 + // replacement is the encoded replacement character. + replacement byte + // decode is the map from encoded byte to UTF-8. + decode [256]utf8Enc + // encoding is the map from runes to encoded bytes. Each entry is a + // uint32: the high 8 bits are the encoded byte and the low 24 bits are + // the rune. The table entries are sorted by ascending rune. + encode [256]uint32 +} + +// NewDecoder implements the encoding.Encoding interface. +func (m *Charmap) NewDecoder() *encoding.Decoder { + return &encoding.Decoder{Transformer: charmapDecoder{charmap: m}} +} + +// NewEncoder implements the encoding.Encoding interface. +func (m *Charmap) NewEncoder() *encoding.Encoder { + return &encoding.Encoder{Transformer: charmapEncoder{charmap: m}} +} + +// String returns the Charmap's name. +func (m *Charmap) String() string { + return m.name +} + +// ID implements an internal interface. +func (m *Charmap) ID() (mib identifier.MIB, other string) { + return m.mib, "" +} + +// charmapDecoder implements transform.Transformer by decoding to UTF-8. +type charmapDecoder struct { + transform.NopResetter + charmap *Charmap +} + +func (m charmapDecoder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { + for i, c := range src { + if m.charmap.asciiSuperset && c < utf8.RuneSelf { + if nDst >= len(dst) { + err = transform.ErrShortDst + break + } + dst[nDst] = c + nDst++ + nSrc = i + 1 + continue + } + + decode := &m.charmap.decode[c] + n := int(decode.len) + if nDst+n > len(dst) { + err = transform.ErrShortDst + break + } + // It's 15% faster to avoid calling copy for these tiny slices. + for j := 0; j < n; j++ { + dst[nDst] = decode.data[j] + nDst++ + } + nSrc = i + 1 + } + return nDst, nSrc, err +} + +// DecodeByte returns the Charmap's rune decoding of the byte b. +func (m *Charmap) DecodeByte(b byte) rune { + switch x := &m.decode[b]; x.len { + case 1: + return rune(x.data[0]) + case 2: + return rune(x.data[0]&0x1f)<<6 | rune(x.data[1]&0x3f) + default: + return rune(x.data[0]&0x0f)<<12 | rune(x.data[1]&0x3f)<<6 | rune(x.data[2]&0x3f) + } +} + +// charmapEncoder implements transform.Transformer by encoding from UTF-8. +type charmapEncoder struct { + transform.NopResetter + charmap *Charmap +} + +func (m charmapEncoder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { + r, size := rune(0), 0 +loop: + for nSrc < len(src) { + if nDst >= len(dst) { + err = transform.ErrShortDst + break + } + r = rune(src[nSrc]) + + // Decode a 1-byte rune. + if r < utf8.RuneSelf { + if m.charmap.asciiSuperset { + nSrc++ + dst[nDst] = uint8(r) + nDst++ + continue + } + size = 1 + + } else { + // Decode a multi-byte rune. + r, size = utf8.DecodeRune(src[nSrc:]) + if size == 1 { + // All valid runes of size 1 (those below utf8.RuneSelf) were + // handled above. We have invalid UTF-8 or we haven't seen the + // full character yet. + if !atEOF && !utf8.FullRune(src[nSrc:]) { + err = transform.ErrShortSrc + } else { + err = internal.RepertoireError(m.charmap.replacement) + } + break + } + } + + // Binary search in [low, high) for that rune in the m.charmap.encode table. + for low, high := int(m.charmap.low), 0x100; ; { + if low >= high { + err = internal.RepertoireError(m.charmap.replacement) + break loop + } + mid := (low + high) / 2 + got := m.charmap.encode[mid] + gotRune := rune(got & (1<<24 - 1)) + if gotRune < r { + low = mid + 1 + } else if gotRune > r { + high = mid + } else { + dst[nDst] = byte(got >> 24) + nDst++ + break + } + } + nSrc += size + } + return nDst, nSrc, err +} + +// EncodeRune returns the Charmap's byte encoding of the rune r. ok is whether +// r is in the Charmap's repertoire. If not, b is set to the Charmap's +// replacement byte. This is often the ASCII substitute character '\x1a'. +func (m *Charmap) EncodeRune(r rune) (b byte, ok bool) { + if r < utf8.RuneSelf && m.asciiSuperset { + return byte(r), true + } + for low, high := int(m.low), 0x100; ; { + if low >= high { + return m.replacement, false + } + mid := (low + high) / 2 + got := m.encode[mid] + gotRune := rune(got & (1<<24 - 1)) + if gotRune < r { + low = mid + 1 + } else if gotRune > r { + high = mid + } else { + return byte(got >> 24), true + } + } +} diff --git a/vendor/golang.org/x/text/encoding/charmap/tables.go b/vendor/golang.org/x/text/encoding/charmap/tables.go new file mode 100644 index 00000000..cf7281e9 --- /dev/null +++ b/vendor/golang.org/x/text/encoding/charmap/tables.go @@ -0,0 +1,7410 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +package charmap + +import ( + "golang.org/x/text/encoding" + "golang.org/x/text/encoding/internal/identifier" +) + +// CodePage037 is the IBM Code Page 037 encoding. +var CodePage037 *Charmap = &codePage037 + +var codePage037 = Charmap{ + name: "IBM Code Page 037", + mib: identifier.IBM037, + asciiSuperset: false, + low: 0x00, + replacement: 0x3f, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x9c, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x86, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x97, 0x00}}, {2, [3]byte{0xc2, 0x8d, 0x00}}, + {2, [3]byte{0xc2, 0x8e, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x9d, 0x00}}, {2, [3]byte{0xc2, 0x85, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {2, [3]byte{0xc2, 0x87, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x92, 0x00}}, {2, [3]byte{0xc2, 0x8f, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x80, 0x00}}, {2, [3]byte{0xc2, 0x81, 0x00}}, + {2, [3]byte{0xc2, 0x82, 0x00}}, {2, [3]byte{0xc2, 0x83, 0x00}}, + {2, [3]byte{0xc2, 0x84, 0x00}}, {1, [3]byte{0x0a, 0x00, 0x00}}, + {1, [3]byte{0x17, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x88, 0x00}}, {2, [3]byte{0xc2, 0x89, 0x00}}, + {2, [3]byte{0xc2, 0x8a, 0x00}}, {2, [3]byte{0xc2, 0x8b, 0x00}}, + {2, [3]byte{0xc2, 0x8c, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x90, 0x00}}, {2, [3]byte{0xc2, 0x91, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {2, [3]byte{0xc2, 0x93, 0x00}}, + {2, [3]byte{0xc2, 0x94, 0x00}}, {2, [3]byte{0xc2, 0x95, 0x00}}, + {2, [3]byte{0xc2, 0x96, 0x00}}, {1, [3]byte{0x04, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x98, 0x00}}, {2, [3]byte{0xc2, 0x99, 0x00}}, + {2, [3]byte{0xc2, 0x9a, 0x00}}, {2, [3]byte{0xc2, 0x9b, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x9e, 0x00}}, {1, [3]byte{0x1a, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {2, [3]byte{0xc2, 0xa0, 0x00}}, + {2, [3]byte{0xc3, 0xa2, 0x00}}, {2, [3]byte{0xc3, 0xa4, 0x00}}, + {2, [3]byte{0xc3, 0xa0, 0x00}}, {2, [3]byte{0xc3, 0xa1, 0x00}}, + {2, [3]byte{0xc3, 0xa3, 0x00}}, {2, [3]byte{0xc3, 0xa5, 0x00}}, + {2, [3]byte{0xc3, 0xa7, 0x00}}, {2, [3]byte{0xc3, 0xb1, 0x00}}, + {2, [3]byte{0xc2, 0xa2, 0x00}}, {1, [3]byte{0x2e, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x28, 0x00, 0x00}}, + {1, [3]byte{0x2b, 0x00, 0x00}}, {1, [3]byte{0x7c, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {2, [3]byte{0xc3, 0xa9, 0x00}}, + {2, [3]byte{0xc3, 0xaa, 0x00}}, {2, [3]byte{0xc3, 0xab, 0x00}}, + {2, [3]byte{0xc3, 0xa8, 0x00}}, {2, [3]byte{0xc3, 0xad, 0x00}}, + {2, [3]byte{0xc3, 0xae, 0x00}}, {2, [3]byte{0xc3, 0xaf, 0x00}}, + {2, [3]byte{0xc3, 0xac, 0x00}}, {2, [3]byte{0xc3, 0x9f, 0x00}}, + {1, [3]byte{0x21, 0x00, 0x00}}, {1, [3]byte{0x24, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x3b, 0x00, 0x00}}, {2, [3]byte{0xc2, 0xac, 0x00}}, + {1, [3]byte{0x2d, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {2, [3]byte{0xc3, 0x82, 0x00}}, {2, [3]byte{0xc3, 0x84, 0x00}}, + {2, [3]byte{0xc3, 0x80, 0x00}}, {2, [3]byte{0xc3, 0x81, 0x00}}, + {2, [3]byte{0xc3, 0x83, 0x00}}, {2, [3]byte{0xc3, 0x85, 0x00}}, + {2, [3]byte{0xc3, 0x87, 0x00}}, {2, [3]byte{0xc3, 0x91, 0x00}}, + {2, [3]byte{0xc2, 0xa6, 0x00}}, {1, [3]byte{0x2c, 0x00, 0x00}}, + {1, [3]byte{0x25, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {2, [3]byte{0xc3, 0xb8, 0x00}}, {2, [3]byte{0xc3, 0x89, 0x00}}, + {2, [3]byte{0xc3, 0x8a, 0x00}}, {2, [3]byte{0xc3, 0x8b, 0x00}}, + {2, [3]byte{0xc3, 0x88, 0x00}}, {2, [3]byte{0xc3, 0x8d, 0x00}}, + {2, [3]byte{0xc3, 0x8e, 0x00}}, {2, [3]byte{0xc3, 0x8f, 0x00}}, + {2, [3]byte{0xc3, 0x8c, 0x00}}, {1, [3]byte{0x60, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x3d, 0x00, 0x00}}, {1, [3]byte{0x22, 0x00, 0x00}}, + {2, [3]byte{0xc3, 0x98, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0xab, 0x00}}, {2, [3]byte{0xc2, 0xbb, 0x00}}, + {2, [3]byte{0xc3, 0xb0, 0x00}}, {2, [3]byte{0xc3, 0xbd, 0x00}}, + {2, [3]byte{0xc3, 0xbe, 0x00}}, {2, [3]byte{0xc2, 0xb1, 0x00}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {1, [3]byte{0x6a, 0x00, 0x00}}, + {1, [3]byte{0x6b, 0x00, 0x00}}, {1, [3]byte{0x6c, 0x00, 0x00}}, + {1, [3]byte{0x6d, 0x00, 0x00}}, {1, [3]byte{0x6e, 0x00, 0x00}}, + {1, [3]byte{0x6f, 0x00, 0x00}}, {1, [3]byte{0x70, 0x00, 0x00}}, + {1, [3]byte{0x71, 0x00, 0x00}}, {1, [3]byte{0x72, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0xaa, 0x00}}, {2, [3]byte{0xc2, 0xba, 0x00}}, + {2, [3]byte{0xc3, 0xa6, 0x00}}, {2, [3]byte{0xc2, 0xb8, 0x00}}, + {2, [3]byte{0xc3, 0x86, 0x00}}, {2, [3]byte{0xc2, 0xa4, 0x00}}, + {2, [3]byte{0xc2, 0xb5, 0x00}}, {1, [3]byte{0x7e, 0x00, 0x00}}, + {1, [3]byte{0x73, 0x00, 0x00}}, {1, [3]byte{0x74, 0x00, 0x00}}, + {1, [3]byte{0x75, 0x00, 0x00}}, {1, [3]byte{0x76, 0x00, 0x00}}, + {1, [3]byte{0x77, 0x00, 0x00}}, {1, [3]byte{0x78, 0x00, 0x00}}, + {1, [3]byte{0x79, 0x00, 0x00}}, {1, [3]byte{0x7a, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0xa1, 0x00}}, {2, [3]byte{0xc2, 0xbf, 0x00}}, + {2, [3]byte{0xc3, 0x90, 0x00}}, {2, [3]byte{0xc3, 0x9d, 0x00}}, + {2, [3]byte{0xc3, 0x9e, 0x00}}, {2, [3]byte{0xc2, 0xae, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {2, [3]byte{0xc2, 0xa3, 0x00}}, + {2, [3]byte{0xc2, 0xa5, 0x00}}, {2, [3]byte{0xc2, 0xb7, 0x00}}, + {2, [3]byte{0xc2, 0xa9, 0x00}}, {2, [3]byte{0xc2, 0xa7, 0x00}}, + {2, [3]byte{0xc2, 0xb6, 0x00}}, {2, [3]byte{0xc2, 0xbc, 0x00}}, + {2, [3]byte{0xc2, 0xbd, 0x00}}, {2, [3]byte{0xc2, 0xbe, 0x00}}, + {1, [3]byte{0x5b, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0xaf, 0x00}}, {2, [3]byte{0xc2, 0xa8, 0x00}}, + {2, [3]byte{0xc2, 0xb4, 0x00}}, {2, [3]byte{0xc3, 0x97, 0x00}}, + {1, [3]byte{0x7b, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0xad, 0x00}}, {2, [3]byte{0xc3, 0xb4, 0x00}}, + {2, [3]byte{0xc3, 0xb6, 0x00}}, {2, [3]byte{0xc3, 0xb2, 0x00}}, + {2, [3]byte{0xc3, 0xb3, 0x00}}, {2, [3]byte{0xc3, 0xb5, 0x00}}, + {1, [3]byte{0x7d, 0x00, 0x00}}, {1, [3]byte{0x4a, 0x00, 0x00}}, + {1, [3]byte{0x4b, 0x00, 0x00}}, {1, [3]byte{0x4c, 0x00, 0x00}}, + {1, [3]byte{0x4d, 0x00, 0x00}}, {1, [3]byte{0x4e, 0x00, 0x00}}, + {1, [3]byte{0x4f, 0x00, 0x00}}, {1, [3]byte{0x50, 0x00, 0x00}}, + {1, [3]byte{0x51, 0x00, 0x00}}, {1, [3]byte{0x52, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0xb9, 0x00}}, {2, [3]byte{0xc3, 0xbb, 0x00}}, + {2, [3]byte{0xc3, 0xbc, 0x00}}, {2, [3]byte{0xc3, 0xb9, 0x00}}, + {2, [3]byte{0xc3, 0xba, 0x00}}, {2, [3]byte{0xc3, 0xbf, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {2, [3]byte{0xc3, 0xb7, 0x00}}, + {1, [3]byte{0x53, 0x00, 0x00}}, {1, [3]byte{0x54, 0x00, 0x00}}, + {1, [3]byte{0x55, 0x00, 0x00}}, {1, [3]byte{0x56, 0x00, 0x00}}, + {1, [3]byte{0x57, 0x00, 0x00}}, {1, [3]byte{0x58, 0x00, 0x00}}, + {1, [3]byte{0x59, 0x00, 0x00}}, {1, [3]byte{0x5a, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0xb2, 0x00}}, {2, [3]byte{0xc3, 0x94, 0x00}}, + {2, [3]byte{0xc3, 0x96, 0x00}}, {2, [3]byte{0xc3, 0x92, 0x00}}, + {2, [3]byte{0xc3, 0x93, 0x00}}, {2, [3]byte{0xc3, 0x95, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0xb3, 0x00}}, {2, [3]byte{0xc3, 0x9b, 0x00}}, + {2, [3]byte{0xc3, 0x9c, 0x00}}, {2, [3]byte{0xc3, 0x99, 0x00}}, + {2, [3]byte{0xc3, 0x9a, 0x00}}, {2, [3]byte{0xc2, 0x9f, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x37000004, 0x2d000005, 0x2e000006, 0x2f000007, + 0x16000008, 0x05000009, 0x2500000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x3c000014, 0x3d000015, 0x32000016, 0x26000017, + 0x18000018, 0x19000019, 0x3f00001a, 0x2700001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x40000020, 0x5a000021, 0x7f000022, 0x7b000023, 0x5b000024, 0x6c000025, 0x50000026, 0x7d000027, + 0x4d000028, 0x5d000029, 0x5c00002a, 0x4e00002b, 0x6b00002c, 0x6000002d, 0x4b00002e, 0x6100002f, + 0xf0000030, 0xf1000031, 0xf2000032, 0xf3000033, 0xf4000034, 0xf5000035, 0xf6000036, 0xf7000037, + 0xf8000038, 0xf9000039, 0x7a00003a, 0x5e00003b, 0x4c00003c, 0x7e00003d, 0x6e00003e, 0x6f00003f, + 0x7c000040, 0xc1000041, 0xc2000042, 0xc3000043, 0xc4000044, 0xc5000045, 0xc6000046, 0xc7000047, + 0xc8000048, 0xc9000049, 0xd100004a, 0xd200004b, 0xd300004c, 0xd400004d, 0xd500004e, 0xd600004f, + 0xd7000050, 0xd8000051, 0xd9000052, 0xe2000053, 0xe3000054, 0xe4000055, 0xe5000056, 0xe6000057, + 0xe7000058, 0xe8000059, 0xe900005a, 0xba00005b, 0xe000005c, 0xbb00005d, 0xb000005e, 0x6d00005f, + 0x79000060, 0x81000061, 0x82000062, 0x83000063, 0x84000064, 0x85000065, 0x86000066, 0x87000067, + 0x88000068, 0x89000069, 0x9100006a, 0x9200006b, 0x9300006c, 0x9400006d, 0x9500006e, 0x9600006f, + 0x97000070, 0x98000071, 0x99000072, 0xa2000073, 0xa3000074, 0xa4000075, 0xa5000076, 0xa6000077, + 0xa7000078, 0xa8000079, 0xa900007a, 0xc000007b, 0x4f00007c, 0xd000007d, 0xa100007e, 0x0700007f, + 0x20000080, 0x21000081, 0x22000082, 0x23000083, 0x24000084, 0x15000085, 0x06000086, 0x17000087, + 0x28000088, 0x29000089, 0x2a00008a, 0x2b00008b, 0x2c00008c, 0x0900008d, 0x0a00008e, 0x1b00008f, + 0x30000090, 0x31000091, 0x1a000092, 0x33000093, 0x34000094, 0x35000095, 0x36000096, 0x08000097, + 0x38000098, 0x39000099, 0x3a00009a, 0x3b00009b, 0x0400009c, 0x1400009d, 0x3e00009e, 0xff00009f, + 0x410000a0, 0xaa0000a1, 0x4a0000a2, 0xb10000a3, 0x9f0000a4, 0xb20000a5, 0x6a0000a6, 0xb50000a7, + 0xbd0000a8, 0xb40000a9, 0x9a0000aa, 0x8a0000ab, 0x5f0000ac, 0xca0000ad, 0xaf0000ae, 0xbc0000af, + 0x900000b0, 0x8f0000b1, 0xea0000b2, 0xfa0000b3, 0xbe0000b4, 0xa00000b5, 0xb60000b6, 0xb30000b7, + 0x9d0000b8, 0xda0000b9, 0x9b0000ba, 0x8b0000bb, 0xb70000bc, 0xb80000bd, 0xb90000be, 0xab0000bf, + 0x640000c0, 0x650000c1, 0x620000c2, 0x660000c3, 0x630000c4, 0x670000c5, 0x9e0000c6, 0x680000c7, + 0x740000c8, 0x710000c9, 0x720000ca, 0x730000cb, 0x780000cc, 0x750000cd, 0x760000ce, 0x770000cf, + 0xac0000d0, 0x690000d1, 0xed0000d2, 0xee0000d3, 0xeb0000d4, 0xef0000d5, 0xec0000d6, 0xbf0000d7, + 0x800000d8, 0xfd0000d9, 0xfe0000da, 0xfb0000db, 0xfc0000dc, 0xad0000dd, 0xae0000de, 0x590000df, + 0x440000e0, 0x450000e1, 0x420000e2, 0x460000e3, 0x430000e4, 0x470000e5, 0x9c0000e6, 0x480000e7, + 0x540000e8, 0x510000e9, 0x520000ea, 0x530000eb, 0x580000ec, 0x550000ed, 0x560000ee, 0x570000ef, + 0x8c0000f0, 0x490000f1, 0xcd0000f2, 0xce0000f3, 0xcb0000f4, 0xcf0000f5, 0xcc0000f6, 0xe10000f7, + 0x700000f8, 0xdd0000f9, 0xde0000fa, 0xdb0000fb, 0xdc0000fc, 0x8d0000fd, 0x8e0000fe, 0xdf0000ff, + }, +} + +// CodePage437 is the IBM Code Page 437 encoding. +var CodePage437 *Charmap = &codePage437 + +var codePage437 = Charmap{ + name: "IBM Code Page 437", + mib: identifier.PC8CodePage437, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {2, [3]byte{0xc3, 0x87, 0x00}}, {2, [3]byte{0xc3, 0xbc, 0x00}}, + {2, [3]byte{0xc3, 0xa9, 0x00}}, {2, [3]byte{0xc3, 0xa2, 0x00}}, + {2, [3]byte{0xc3, 0xa4, 0x00}}, {2, [3]byte{0xc3, 0xa0, 0x00}}, + {2, [3]byte{0xc3, 0xa5, 0x00}}, {2, [3]byte{0xc3, 0xa7, 0x00}}, + {2, [3]byte{0xc3, 0xaa, 0x00}}, {2, [3]byte{0xc3, 0xab, 0x00}}, + {2, [3]byte{0xc3, 0xa8, 0x00}}, {2, [3]byte{0xc3, 0xaf, 0x00}}, + {2, [3]byte{0xc3, 0xae, 0x00}}, {2, [3]byte{0xc3, 0xac, 0x00}}, + {2, [3]byte{0xc3, 0x84, 0x00}}, {2, [3]byte{0xc3, 0x85, 0x00}}, + {2, [3]byte{0xc3, 0x89, 0x00}}, {2, [3]byte{0xc3, 0xa6, 0x00}}, + {2, [3]byte{0xc3, 0x86, 0x00}}, {2, [3]byte{0xc3, 0xb4, 0x00}}, + {2, [3]byte{0xc3, 0xb6, 0x00}}, {2, [3]byte{0xc3, 0xb2, 0x00}}, + {2, [3]byte{0xc3, 0xbb, 0x00}}, {2, [3]byte{0xc3, 0xb9, 0x00}}, + {2, [3]byte{0xc3, 0xbf, 0x00}}, {2, [3]byte{0xc3, 0x96, 0x00}}, + {2, [3]byte{0xc3, 0x9c, 0x00}}, {2, [3]byte{0xc2, 0xa2, 0x00}}, + {2, [3]byte{0xc2, 0xa3, 0x00}}, {2, [3]byte{0xc2, 0xa5, 0x00}}, + {3, [3]byte{0xe2, 0x82, 0xa7}}, {2, [3]byte{0xc6, 0x92, 0x00}}, + {2, [3]byte{0xc3, 0xa1, 0x00}}, {2, [3]byte{0xc3, 0xad, 0x00}}, + {2, [3]byte{0xc3, 0xb3, 0x00}}, {2, [3]byte{0xc3, 0xba, 0x00}}, + {2, [3]byte{0xc3, 0xb1, 0x00}}, {2, [3]byte{0xc3, 0x91, 0x00}}, + {2, [3]byte{0xc2, 0xaa, 0x00}}, {2, [3]byte{0xc2, 0xba, 0x00}}, + {2, [3]byte{0xc2, 0xbf, 0x00}}, {3, [3]byte{0xe2, 0x8c, 0x90}}, + {2, [3]byte{0xc2, 0xac, 0x00}}, {2, [3]byte{0xc2, 0xbd, 0x00}}, + {2, [3]byte{0xc2, 0xbc, 0x00}}, {2, [3]byte{0xc2, 0xa1, 0x00}}, + {2, [3]byte{0xc2, 0xab, 0x00}}, {2, [3]byte{0xc2, 0xbb, 0x00}}, + {3, [3]byte{0xe2, 0x96, 0x91}}, {3, [3]byte{0xe2, 0x96, 0x92}}, + {3, [3]byte{0xe2, 0x96, 0x93}}, {3, [3]byte{0xe2, 0x94, 0x82}}, + {3, [3]byte{0xe2, 0x94, 0xa4}}, {3, [3]byte{0xe2, 0x95, 0xa1}}, + {3, [3]byte{0xe2, 0x95, 0xa2}}, {3, [3]byte{0xe2, 0x95, 0x96}}, + {3, [3]byte{0xe2, 0x95, 0x95}}, {3, [3]byte{0xe2, 0x95, 0xa3}}, + {3, [3]byte{0xe2, 0x95, 0x91}}, {3, [3]byte{0xe2, 0x95, 0x97}}, + {3, [3]byte{0xe2, 0x95, 0x9d}}, {3, [3]byte{0xe2, 0x95, 0x9c}}, + {3, [3]byte{0xe2, 0x95, 0x9b}}, {3, [3]byte{0xe2, 0x94, 0x90}}, + {3, [3]byte{0xe2, 0x94, 0x94}}, {3, [3]byte{0xe2, 0x94, 0xb4}}, + {3, [3]byte{0xe2, 0x94, 0xac}}, {3, [3]byte{0xe2, 0x94, 0x9c}}, + {3, [3]byte{0xe2, 0x94, 0x80}}, {3, [3]byte{0xe2, 0x94, 0xbc}}, + {3, [3]byte{0xe2, 0x95, 0x9e}}, {3, [3]byte{0xe2, 0x95, 0x9f}}, + {3, [3]byte{0xe2, 0x95, 0x9a}}, {3, [3]byte{0xe2, 0x95, 0x94}}, + {3, [3]byte{0xe2, 0x95, 0xa9}}, {3, [3]byte{0xe2, 0x95, 0xa6}}, + {3, [3]byte{0xe2, 0x95, 0xa0}}, {3, [3]byte{0xe2, 0x95, 0x90}}, + {3, [3]byte{0xe2, 0x95, 0xac}}, {3, [3]byte{0xe2, 0x95, 0xa7}}, + {3, [3]byte{0xe2, 0x95, 0xa8}}, {3, [3]byte{0xe2, 0x95, 0xa4}}, + {3, [3]byte{0xe2, 0x95, 0xa5}}, {3, [3]byte{0xe2, 0x95, 0x99}}, + {3, [3]byte{0xe2, 0x95, 0x98}}, {3, [3]byte{0xe2, 0x95, 0x92}}, + {3, [3]byte{0xe2, 0x95, 0x93}}, {3, [3]byte{0xe2, 0x95, 0xab}}, + {3, [3]byte{0xe2, 0x95, 0xaa}}, {3, [3]byte{0xe2, 0x94, 0x98}}, + {3, [3]byte{0xe2, 0x94, 0x8c}}, {3, [3]byte{0xe2, 0x96, 0x88}}, + {3, [3]byte{0xe2, 0x96, 0x84}}, {3, [3]byte{0xe2, 0x96, 0x8c}}, + {3, [3]byte{0xe2, 0x96, 0x90}}, {3, [3]byte{0xe2, 0x96, 0x80}}, + {2, [3]byte{0xce, 0xb1, 0x00}}, {2, [3]byte{0xc3, 0x9f, 0x00}}, + {2, [3]byte{0xce, 0x93, 0x00}}, {2, [3]byte{0xcf, 0x80, 0x00}}, + {2, [3]byte{0xce, 0xa3, 0x00}}, {2, [3]byte{0xcf, 0x83, 0x00}}, + {2, [3]byte{0xc2, 0xb5, 0x00}}, {2, [3]byte{0xcf, 0x84, 0x00}}, + {2, [3]byte{0xce, 0xa6, 0x00}}, {2, [3]byte{0xce, 0x98, 0x00}}, + {2, [3]byte{0xce, 0xa9, 0x00}}, {2, [3]byte{0xce, 0xb4, 0x00}}, + {3, [3]byte{0xe2, 0x88, 0x9e}}, {2, [3]byte{0xcf, 0x86, 0x00}}, + {2, [3]byte{0xce, 0xb5, 0x00}}, {3, [3]byte{0xe2, 0x88, 0xa9}}, + {3, [3]byte{0xe2, 0x89, 0xa1}}, {2, [3]byte{0xc2, 0xb1, 0x00}}, + {3, [3]byte{0xe2, 0x89, 0xa5}}, {3, [3]byte{0xe2, 0x89, 0xa4}}, + {3, [3]byte{0xe2, 0x8c, 0xa0}}, {3, [3]byte{0xe2, 0x8c, 0xa1}}, + {2, [3]byte{0xc3, 0xb7, 0x00}}, {3, [3]byte{0xe2, 0x89, 0x88}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {3, [3]byte{0xe2, 0x88, 0x99}}, + {2, [3]byte{0xc2, 0xb7, 0x00}}, {3, [3]byte{0xe2, 0x88, 0x9a}}, + {3, [3]byte{0xe2, 0x81, 0xbf}}, {2, [3]byte{0xc2, 0xb2, 0x00}}, + {3, [3]byte{0xe2, 0x96, 0xa0}}, {2, [3]byte{0xc2, 0xa0, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xff0000a0, 0xad0000a1, 0x9b0000a2, 0x9c0000a3, 0x9d0000a5, 0xa60000aa, 0xae0000ab, 0xaa0000ac, + 0xf80000b0, 0xf10000b1, 0xfd0000b2, 0xe60000b5, 0xfa0000b7, 0xa70000ba, 0xaf0000bb, 0xac0000bc, + 0xab0000bd, 0xa80000bf, 0x8e0000c4, 0x8f0000c5, 0x920000c6, 0x800000c7, 0x900000c9, 0xa50000d1, + 0x990000d6, 0x9a0000dc, 0xe10000df, 0x850000e0, 0xa00000e1, 0x830000e2, 0x840000e4, 0x860000e5, + 0x910000e6, 0x870000e7, 0x8a0000e8, 0x820000e9, 0x880000ea, 0x890000eb, 0x8d0000ec, 0xa10000ed, + 0x8c0000ee, 0x8b0000ef, 0xa40000f1, 0x950000f2, 0xa20000f3, 0x930000f4, 0x940000f6, 0xf60000f7, + 0x970000f9, 0xa30000fa, 0x960000fb, 0x810000fc, 0x980000ff, 0x9f000192, 0xe2000393, 0xe9000398, + 0xe40003a3, 0xe80003a6, 0xea0003a9, 0xe00003b1, 0xeb0003b4, 0xee0003b5, 0xe30003c0, 0xe50003c3, + 0xe70003c4, 0xed0003c6, 0xfc00207f, 0x9e0020a7, 0xf9002219, 0xfb00221a, 0xec00221e, 0xef002229, + 0xf7002248, 0xf0002261, 0xf3002264, 0xf2002265, 0xa9002310, 0xf4002320, 0xf5002321, 0xc4002500, + 0xb3002502, 0xda00250c, 0xbf002510, 0xc0002514, 0xd9002518, 0xc300251c, 0xb4002524, 0xc200252c, + 0xc1002534, 0xc500253c, 0xcd002550, 0xba002551, 0xd5002552, 0xd6002553, 0xc9002554, 0xb8002555, + 0xb7002556, 0xbb002557, 0xd4002558, 0xd3002559, 0xc800255a, 0xbe00255b, 0xbd00255c, 0xbc00255d, + 0xc600255e, 0xc700255f, 0xcc002560, 0xb5002561, 0xb6002562, 0xb9002563, 0xd1002564, 0xd2002565, + 0xcb002566, 0xcf002567, 0xd0002568, 0xca002569, 0xd800256a, 0xd700256b, 0xce00256c, 0xdf002580, + 0xdc002584, 0xdb002588, 0xdd00258c, 0xde002590, 0xb0002591, 0xb1002592, 0xb2002593, 0xfe0025a0, + }, +} + +// CodePage850 is the IBM Code Page 850 encoding. +var CodePage850 *Charmap = &codePage850 + +var codePage850 = Charmap{ + name: "IBM Code Page 850", + mib: identifier.PC850Multilingual, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {2, [3]byte{0xc3, 0x87, 0x00}}, {2, [3]byte{0xc3, 0xbc, 0x00}}, + {2, [3]byte{0xc3, 0xa9, 0x00}}, {2, [3]byte{0xc3, 0xa2, 0x00}}, + {2, [3]byte{0xc3, 0xa4, 0x00}}, {2, [3]byte{0xc3, 0xa0, 0x00}}, + {2, [3]byte{0xc3, 0xa5, 0x00}}, {2, [3]byte{0xc3, 0xa7, 0x00}}, + {2, [3]byte{0xc3, 0xaa, 0x00}}, {2, [3]byte{0xc3, 0xab, 0x00}}, + {2, [3]byte{0xc3, 0xa8, 0x00}}, {2, [3]byte{0xc3, 0xaf, 0x00}}, + {2, [3]byte{0xc3, 0xae, 0x00}}, {2, [3]byte{0xc3, 0xac, 0x00}}, + {2, [3]byte{0xc3, 0x84, 0x00}}, {2, [3]byte{0xc3, 0x85, 0x00}}, + {2, [3]byte{0xc3, 0x89, 0x00}}, {2, [3]byte{0xc3, 0xa6, 0x00}}, + {2, [3]byte{0xc3, 0x86, 0x00}}, {2, [3]byte{0xc3, 0xb4, 0x00}}, + {2, [3]byte{0xc3, 0xb6, 0x00}}, {2, [3]byte{0xc3, 0xb2, 0x00}}, + {2, [3]byte{0xc3, 0xbb, 0x00}}, {2, [3]byte{0xc3, 0xb9, 0x00}}, + {2, [3]byte{0xc3, 0xbf, 0x00}}, {2, [3]byte{0xc3, 0x96, 0x00}}, + {2, [3]byte{0xc3, 0x9c, 0x00}}, {2, [3]byte{0xc3, 0xb8, 0x00}}, + {2, [3]byte{0xc2, 0xa3, 0x00}}, {2, [3]byte{0xc3, 0x98, 0x00}}, + {2, [3]byte{0xc3, 0x97, 0x00}}, {2, [3]byte{0xc6, 0x92, 0x00}}, + {2, [3]byte{0xc3, 0xa1, 0x00}}, {2, [3]byte{0xc3, 0xad, 0x00}}, + {2, [3]byte{0xc3, 0xb3, 0x00}}, {2, [3]byte{0xc3, 0xba, 0x00}}, + {2, [3]byte{0xc3, 0xb1, 0x00}}, {2, [3]byte{0xc3, 0x91, 0x00}}, + {2, [3]byte{0xc2, 0xaa, 0x00}}, {2, [3]byte{0xc2, 0xba, 0x00}}, + {2, [3]byte{0xc2, 0xbf, 0x00}}, {2, [3]byte{0xc2, 0xae, 0x00}}, + {2, [3]byte{0xc2, 0xac, 0x00}}, {2, [3]byte{0xc2, 0xbd, 0x00}}, + {2, [3]byte{0xc2, 0xbc, 0x00}}, {2, [3]byte{0xc2, 0xa1, 0x00}}, + {2, [3]byte{0xc2, 0xab, 0x00}}, {2, [3]byte{0xc2, 0xbb, 0x00}}, + {3, [3]byte{0xe2, 0x96, 0x91}}, {3, [3]byte{0xe2, 0x96, 0x92}}, + {3, [3]byte{0xe2, 0x96, 0x93}}, {3, [3]byte{0xe2, 0x94, 0x82}}, + {3, [3]byte{0xe2, 0x94, 0xa4}}, {2, [3]byte{0xc3, 0x81, 0x00}}, + {2, [3]byte{0xc3, 0x82, 0x00}}, {2, [3]byte{0xc3, 0x80, 0x00}}, + {2, [3]byte{0xc2, 0xa9, 0x00}}, {3, [3]byte{0xe2, 0x95, 0xa3}}, + {3, [3]byte{0xe2, 0x95, 0x91}}, {3, [3]byte{0xe2, 0x95, 0x97}}, + {3, [3]byte{0xe2, 0x95, 0x9d}}, {2, [3]byte{0xc2, 0xa2, 0x00}}, + {2, [3]byte{0xc2, 0xa5, 0x00}}, {3, [3]byte{0xe2, 0x94, 0x90}}, + {3, [3]byte{0xe2, 0x94, 0x94}}, {3, [3]byte{0xe2, 0x94, 0xb4}}, + {3, [3]byte{0xe2, 0x94, 0xac}}, {3, [3]byte{0xe2, 0x94, 0x9c}}, + {3, [3]byte{0xe2, 0x94, 0x80}}, {3, [3]byte{0xe2, 0x94, 0xbc}}, + {2, [3]byte{0xc3, 0xa3, 0x00}}, {2, [3]byte{0xc3, 0x83, 0x00}}, + {3, [3]byte{0xe2, 0x95, 0x9a}}, {3, [3]byte{0xe2, 0x95, 0x94}}, + {3, [3]byte{0xe2, 0x95, 0xa9}}, {3, [3]byte{0xe2, 0x95, 0xa6}}, + {3, [3]byte{0xe2, 0x95, 0xa0}}, {3, [3]byte{0xe2, 0x95, 0x90}}, + {3, [3]byte{0xe2, 0x95, 0xac}}, {2, [3]byte{0xc2, 0xa4, 0x00}}, + {2, [3]byte{0xc3, 0xb0, 0x00}}, {2, [3]byte{0xc3, 0x90, 0x00}}, + {2, [3]byte{0xc3, 0x8a, 0x00}}, {2, [3]byte{0xc3, 0x8b, 0x00}}, + {2, [3]byte{0xc3, 0x88, 0x00}}, {2, [3]byte{0xc4, 0xb1, 0x00}}, + {2, [3]byte{0xc3, 0x8d, 0x00}}, {2, [3]byte{0xc3, 0x8e, 0x00}}, + {2, [3]byte{0xc3, 0x8f, 0x00}}, {3, [3]byte{0xe2, 0x94, 0x98}}, + {3, [3]byte{0xe2, 0x94, 0x8c}}, {3, [3]byte{0xe2, 0x96, 0x88}}, + {3, [3]byte{0xe2, 0x96, 0x84}}, {2, [3]byte{0xc2, 0xa6, 0x00}}, + {2, [3]byte{0xc3, 0x8c, 0x00}}, {3, [3]byte{0xe2, 0x96, 0x80}}, + {2, [3]byte{0xc3, 0x93, 0x00}}, {2, [3]byte{0xc3, 0x9f, 0x00}}, + {2, [3]byte{0xc3, 0x94, 0x00}}, {2, [3]byte{0xc3, 0x92, 0x00}}, + {2, [3]byte{0xc3, 0xb5, 0x00}}, {2, [3]byte{0xc3, 0x95, 0x00}}, + {2, [3]byte{0xc2, 0xb5, 0x00}}, {2, [3]byte{0xc3, 0xbe, 0x00}}, + {2, [3]byte{0xc3, 0x9e, 0x00}}, {2, [3]byte{0xc3, 0x9a, 0x00}}, + {2, [3]byte{0xc3, 0x9b, 0x00}}, {2, [3]byte{0xc3, 0x99, 0x00}}, + {2, [3]byte{0xc3, 0xbd, 0x00}}, {2, [3]byte{0xc3, 0x9d, 0x00}}, + {2, [3]byte{0xc2, 0xaf, 0x00}}, {2, [3]byte{0xc2, 0xb4, 0x00}}, + {2, [3]byte{0xc2, 0xad, 0x00}}, {2, [3]byte{0xc2, 0xb1, 0x00}}, + {3, [3]byte{0xe2, 0x80, 0x97}}, {2, [3]byte{0xc2, 0xbe, 0x00}}, + {2, [3]byte{0xc2, 0xb6, 0x00}}, {2, [3]byte{0xc2, 0xa7, 0x00}}, + {2, [3]byte{0xc3, 0xb7, 0x00}}, {2, [3]byte{0xc2, 0xb8, 0x00}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {2, [3]byte{0xc2, 0xa8, 0x00}}, + {2, [3]byte{0xc2, 0xb7, 0x00}}, {2, [3]byte{0xc2, 0xb9, 0x00}}, + {2, [3]byte{0xc2, 0xb3, 0x00}}, {2, [3]byte{0xc2, 0xb2, 0x00}}, + {3, [3]byte{0xe2, 0x96, 0xa0}}, {2, [3]byte{0xc2, 0xa0, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xff0000a0, 0xad0000a1, 0xbd0000a2, 0x9c0000a3, 0xcf0000a4, 0xbe0000a5, 0xdd0000a6, 0xf50000a7, + 0xf90000a8, 0xb80000a9, 0xa60000aa, 0xae0000ab, 0xaa0000ac, 0xf00000ad, 0xa90000ae, 0xee0000af, + 0xf80000b0, 0xf10000b1, 0xfd0000b2, 0xfc0000b3, 0xef0000b4, 0xe60000b5, 0xf40000b6, 0xfa0000b7, + 0xf70000b8, 0xfb0000b9, 0xa70000ba, 0xaf0000bb, 0xac0000bc, 0xab0000bd, 0xf30000be, 0xa80000bf, + 0xb70000c0, 0xb50000c1, 0xb60000c2, 0xc70000c3, 0x8e0000c4, 0x8f0000c5, 0x920000c6, 0x800000c7, + 0xd40000c8, 0x900000c9, 0xd20000ca, 0xd30000cb, 0xde0000cc, 0xd60000cd, 0xd70000ce, 0xd80000cf, + 0xd10000d0, 0xa50000d1, 0xe30000d2, 0xe00000d3, 0xe20000d4, 0xe50000d5, 0x990000d6, 0x9e0000d7, + 0x9d0000d8, 0xeb0000d9, 0xe90000da, 0xea0000db, 0x9a0000dc, 0xed0000dd, 0xe80000de, 0xe10000df, + 0x850000e0, 0xa00000e1, 0x830000e2, 0xc60000e3, 0x840000e4, 0x860000e5, 0x910000e6, 0x870000e7, + 0x8a0000e8, 0x820000e9, 0x880000ea, 0x890000eb, 0x8d0000ec, 0xa10000ed, 0x8c0000ee, 0x8b0000ef, + 0xd00000f0, 0xa40000f1, 0x950000f2, 0xa20000f3, 0x930000f4, 0xe40000f5, 0x940000f6, 0xf60000f7, + 0x9b0000f8, 0x970000f9, 0xa30000fa, 0x960000fb, 0x810000fc, 0xec0000fd, 0xe70000fe, 0x980000ff, + 0xd5000131, 0x9f000192, 0xf2002017, 0xc4002500, 0xb3002502, 0xda00250c, 0xbf002510, 0xc0002514, + 0xd9002518, 0xc300251c, 0xb4002524, 0xc200252c, 0xc1002534, 0xc500253c, 0xcd002550, 0xba002551, + 0xc9002554, 0xbb002557, 0xc800255a, 0xbc00255d, 0xcc002560, 0xb9002563, 0xcb002566, 0xca002569, + 0xce00256c, 0xdf002580, 0xdc002584, 0xdb002588, 0xb0002591, 0xb1002592, 0xb2002593, 0xfe0025a0, + }, +} + +// CodePage852 is the IBM Code Page 852 encoding. +var CodePage852 *Charmap = &codePage852 + +var codePage852 = Charmap{ + name: "IBM Code Page 852", + mib: identifier.PCp852, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {2, [3]byte{0xc3, 0x87, 0x00}}, {2, [3]byte{0xc3, 0xbc, 0x00}}, + {2, [3]byte{0xc3, 0xa9, 0x00}}, {2, [3]byte{0xc3, 0xa2, 0x00}}, + {2, [3]byte{0xc3, 0xa4, 0x00}}, {2, [3]byte{0xc5, 0xaf, 0x00}}, + {2, [3]byte{0xc4, 0x87, 0x00}}, {2, [3]byte{0xc3, 0xa7, 0x00}}, + {2, [3]byte{0xc5, 0x82, 0x00}}, {2, [3]byte{0xc3, 0xab, 0x00}}, + {2, [3]byte{0xc5, 0x90, 0x00}}, {2, [3]byte{0xc5, 0x91, 0x00}}, + {2, [3]byte{0xc3, 0xae, 0x00}}, {2, [3]byte{0xc5, 0xb9, 0x00}}, + {2, [3]byte{0xc3, 0x84, 0x00}}, {2, [3]byte{0xc4, 0x86, 0x00}}, + {2, [3]byte{0xc3, 0x89, 0x00}}, {2, [3]byte{0xc4, 0xb9, 0x00}}, + {2, [3]byte{0xc4, 0xba, 0x00}}, {2, [3]byte{0xc3, 0xb4, 0x00}}, + {2, [3]byte{0xc3, 0xb6, 0x00}}, {2, [3]byte{0xc4, 0xbd, 0x00}}, + {2, [3]byte{0xc4, 0xbe, 0x00}}, {2, [3]byte{0xc5, 0x9a, 0x00}}, + {2, [3]byte{0xc5, 0x9b, 0x00}}, {2, [3]byte{0xc3, 0x96, 0x00}}, + {2, [3]byte{0xc3, 0x9c, 0x00}}, {2, [3]byte{0xc5, 0xa4, 0x00}}, + {2, [3]byte{0xc5, 0xa5, 0x00}}, {2, [3]byte{0xc5, 0x81, 0x00}}, + {2, [3]byte{0xc3, 0x97, 0x00}}, {2, [3]byte{0xc4, 0x8d, 0x00}}, + {2, [3]byte{0xc3, 0xa1, 0x00}}, {2, [3]byte{0xc3, 0xad, 0x00}}, + {2, [3]byte{0xc3, 0xb3, 0x00}}, {2, [3]byte{0xc3, 0xba, 0x00}}, + {2, [3]byte{0xc4, 0x84, 0x00}}, {2, [3]byte{0xc4, 0x85, 0x00}}, + {2, [3]byte{0xc5, 0xbd, 0x00}}, {2, [3]byte{0xc5, 0xbe, 0x00}}, + {2, [3]byte{0xc4, 0x98, 0x00}}, {2, [3]byte{0xc4, 0x99, 0x00}}, + {2, [3]byte{0xc2, 0xac, 0x00}}, {2, [3]byte{0xc5, 0xba, 0x00}}, + {2, [3]byte{0xc4, 0x8c, 0x00}}, {2, [3]byte{0xc5, 0x9f, 0x00}}, + {2, [3]byte{0xc2, 0xab, 0x00}}, {2, [3]byte{0xc2, 0xbb, 0x00}}, + {3, [3]byte{0xe2, 0x96, 0x91}}, {3, [3]byte{0xe2, 0x96, 0x92}}, + {3, [3]byte{0xe2, 0x96, 0x93}}, {3, [3]byte{0xe2, 0x94, 0x82}}, + {3, [3]byte{0xe2, 0x94, 0xa4}}, {2, [3]byte{0xc3, 0x81, 0x00}}, + {2, [3]byte{0xc3, 0x82, 0x00}}, {2, [3]byte{0xc4, 0x9a, 0x00}}, + {2, [3]byte{0xc5, 0x9e, 0x00}}, {3, [3]byte{0xe2, 0x95, 0xa3}}, + {3, [3]byte{0xe2, 0x95, 0x91}}, {3, [3]byte{0xe2, 0x95, 0x97}}, + {3, [3]byte{0xe2, 0x95, 0x9d}}, {2, [3]byte{0xc5, 0xbb, 0x00}}, + {2, [3]byte{0xc5, 0xbc, 0x00}}, {3, [3]byte{0xe2, 0x94, 0x90}}, + {3, [3]byte{0xe2, 0x94, 0x94}}, {3, [3]byte{0xe2, 0x94, 0xb4}}, + {3, [3]byte{0xe2, 0x94, 0xac}}, {3, [3]byte{0xe2, 0x94, 0x9c}}, + {3, [3]byte{0xe2, 0x94, 0x80}}, {3, [3]byte{0xe2, 0x94, 0xbc}}, + {2, [3]byte{0xc4, 0x82, 0x00}}, {2, [3]byte{0xc4, 0x83, 0x00}}, + {3, [3]byte{0xe2, 0x95, 0x9a}}, {3, [3]byte{0xe2, 0x95, 0x94}}, + {3, [3]byte{0xe2, 0x95, 0xa9}}, {3, [3]byte{0xe2, 0x95, 0xa6}}, + {3, [3]byte{0xe2, 0x95, 0xa0}}, {3, [3]byte{0xe2, 0x95, 0x90}}, + {3, [3]byte{0xe2, 0x95, 0xac}}, {2, [3]byte{0xc2, 0xa4, 0x00}}, + {2, [3]byte{0xc4, 0x91, 0x00}}, {2, [3]byte{0xc4, 0x90, 0x00}}, + {2, [3]byte{0xc4, 0x8e, 0x00}}, {2, [3]byte{0xc3, 0x8b, 0x00}}, + {2, [3]byte{0xc4, 0x8f, 0x00}}, {2, [3]byte{0xc5, 0x87, 0x00}}, + {2, [3]byte{0xc3, 0x8d, 0x00}}, {2, [3]byte{0xc3, 0x8e, 0x00}}, + {2, [3]byte{0xc4, 0x9b, 0x00}}, {3, [3]byte{0xe2, 0x94, 0x98}}, + {3, [3]byte{0xe2, 0x94, 0x8c}}, {3, [3]byte{0xe2, 0x96, 0x88}}, + {3, [3]byte{0xe2, 0x96, 0x84}}, {2, [3]byte{0xc5, 0xa2, 0x00}}, + {2, [3]byte{0xc5, 0xae, 0x00}}, {3, [3]byte{0xe2, 0x96, 0x80}}, + {2, [3]byte{0xc3, 0x93, 0x00}}, {2, [3]byte{0xc3, 0x9f, 0x00}}, + {2, [3]byte{0xc3, 0x94, 0x00}}, {2, [3]byte{0xc5, 0x83, 0x00}}, + {2, [3]byte{0xc5, 0x84, 0x00}}, {2, [3]byte{0xc5, 0x88, 0x00}}, + {2, [3]byte{0xc5, 0xa0, 0x00}}, {2, [3]byte{0xc5, 0xa1, 0x00}}, + {2, [3]byte{0xc5, 0x94, 0x00}}, {2, [3]byte{0xc3, 0x9a, 0x00}}, + {2, [3]byte{0xc5, 0x95, 0x00}}, {2, [3]byte{0xc5, 0xb0, 0x00}}, + {2, [3]byte{0xc3, 0xbd, 0x00}}, {2, [3]byte{0xc3, 0x9d, 0x00}}, + {2, [3]byte{0xc5, 0xa3, 0x00}}, {2, [3]byte{0xc2, 0xb4, 0x00}}, + {2, [3]byte{0xc2, 0xad, 0x00}}, {2, [3]byte{0xcb, 0x9d, 0x00}}, + {2, [3]byte{0xcb, 0x9b, 0x00}}, {2, [3]byte{0xcb, 0x87, 0x00}}, + {2, [3]byte{0xcb, 0x98, 0x00}}, {2, [3]byte{0xc2, 0xa7, 0x00}}, + {2, [3]byte{0xc3, 0xb7, 0x00}}, {2, [3]byte{0xc2, 0xb8, 0x00}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {2, [3]byte{0xc2, 0xa8, 0x00}}, + {2, [3]byte{0xcb, 0x99, 0x00}}, {2, [3]byte{0xc5, 0xb1, 0x00}}, + {2, [3]byte{0xc5, 0x98, 0x00}}, {2, [3]byte{0xc5, 0x99, 0x00}}, + {3, [3]byte{0xe2, 0x96, 0xa0}}, {2, [3]byte{0xc2, 0xa0, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xff0000a0, 0xcf0000a4, 0xf50000a7, 0xf90000a8, 0xae0000ab, 0xaa0000ac, 0xf00000ad, 0xf80000b0, + 0xef0000b4, 0xf70000b8, 0xaf0000bb, 0xb50000c1, 0xb60000c2, 0x8e0000c4, 0x800000c7, 0x900000c9, + 0xd30000cb, 0xd60000cd, 0xd70000ce, 0xe00000d3, 0xe20000d4, 0x990000d6, 0x9e0000d7, 0xe90000da, + 0x9a0000dc, 0xed0000dd, 0xe10000df, 0xa00000e1, 0x830000e2, 0x840000e4, 0x870000e7, 0x820000e9, + 0x890000eb, 0xa10000ed, 0x8c0000ee, 0xa20000f3, 0x930000f4, 0x940000f6, 0xf60000f7, 0xa30000fa, + 0x810000fc, 0xec0000fd, 0xc6000102, 0xc7000103, 0xa4000104, 0xa5000105, 0x8f000106, 0x86000107, + 0xac00010c, 0x9f00010d, 0xd200010e, 0xd400010f, 0xd1000110, 0xd0000111, 0xa8000118, 0xa9000119, + 0xb700011a, 0xd800011b, 0x91000139, 0x9200013a, 0x9500013d, 0x9600013e, 0x9d000141, 0x88000142, + 0xe3000143, 0xe4000144, 0xd5000147, 0xe5000148, 0x8a000150, 0x8b000151, 0xe8000154, 0xea000155, + 0xfc000158, 0xfd000159, 0x9700015a, 0x9800015b, 0xb800015e, 0xad00015f, 0xe6000160, 0xe7000161, + 0xdd000162, 0xee000163, 0x9b000164, 0x9c000165, 0xde00016e, 0x8500016f, 0xeb000170, 0xfb000171, + 0x8d000179, 0xab00017a, 0xbd00017b, 0xbe00017c, 0xa600017d, 0xa700017e, 0xf30002c7, 0xf40002d8, + 0xfa0002d9, 0xf20002db, 0xf10002dd, 0xc4002500, 0xb3002502, 0xda00250c, 0xbf002510, 0xc0002514, + 0xd9002518, 0xc300251c, 0xb4002524, 0xc200252c, 0xc1002534, 0xc500253c, 0xcd002550, 0xba002551, + 0xc9002554, 0xbb002557, 0xc800255a, 0xbc00255d, 0xcc002560, 0xb9002563, 0xcb002566, 0xca002569, + 0xce00256c, 0xdf002580, 0xdc002584, 0xdb002588, 0xb0002591, 0xb1002592, 0xb2002593, 0xfe0025a0, + }, +} + +// CodePage855 is the IBM Code Page 855 encoding. +var CodePage855 *Charmap = &codePage855 + +var codePage855 = Charmap{ + name: "IBM Code Page 855", + mib: identifier.IBM855, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {2, [3]byte{0xd1, 0x92, 0x00}}, {2, [3]byte{0xd0, 0x82, 0x00}}, + {2, [3]byte{0xd1, 0x93, 0x00}}, {2, [3]byte{0xd0, 0x83, 0x00}}, + {2, [3]byte{0xd1, 0x91, 0x00}}, {2, [3]byte{0xd0, 0x81, 0x00}}, + {2, [3]byte{0xd1, 0x94, 0x00}}, {2, [3]byte{0xd0, 0x84, 0x00}}, + {2, [3]byte{0xd1, 0x95, 0x00}}, {2, [3]byte{0xd0, 0x85, 0x00}}, + {2, [3]byte{0xd1, 0x96, 0x00}}, {2, [3]byte{0xd0, 0x86, 0x00}}, + {2, [3]byte{0xd1, 0x97, 0x00}}, {2, [3]byte{0xd0, 0x87, 0x00}}, + {2, [3]byte{0xd1, 0x98, 0x00}}, {2, [3]byte{0xd0, 0x88, 0x00}}, + {2, [3]byte{0xd1, 0x99, 0x00}}, {2, [3]byte{0xd0, 0x89, 0x00}}, + {2, [3]byte{0xd1, 0x9a, 0x00}}, {2, [3]byte{0xd0, 0x8a, 0x00}}, + {2, [3]byte{0xd1, 0x9b, 0x00}}, {2, [3]byte{0xd0, 0x8b, 0x00}}, + {2, [3]byte{0xd1, 0x9c, 0x00}}, {2, [3]byte{0xd0, 0x8c, 0x00}}, + {2, [3]byte{0xd1, 0x9e, 0x00}}, {2, [3]byte{0xd0, 0x8e, 0x00}}, + {2, [3]byte{0xd1, 0x9f, 0x00}}, {2, [3]byte{0xd0, 0x8f, 0x00}}, + {2, [3]byte{0xd1, 0x8e, 0x00}}, {2, [3]byte{0xd0, 0xae, 0x00}}, + {2, [3]byte{0xd1, 0x8a, 0x00}}, {2, [3]byte{0xd0, 0xaa, 0x00}}, + {2, [3]byte{0xd0, 0xb0, 0x00}}, {2, [3]byte{0xd0, 0x90, 0x00}}, + {2, [3]byte{0xd0, 0xb1, 0x00}}, {2, [3]byte{0xd0, 0x91, 0x00}}, + {2, [3]byte{0xd1, 0x86, 0x00}}, {2, [3]byte{0xd0, 0xa6, 0x00}}, + {2, [3]byte{0xd0, 0xb4, 0x00}}, {2, [3]byte{0xd0, 0x94, 0x00}}, + {2, [3]byte{0xd0, 0xb5, 0x00}}, {2, [3]byte{0xd0, 0x95, 0x00}}, + {2, [3]byte{0xd1, 0x84, 0x00}}, {2, [3]byte{0xd0, 0xa4, 0x00}}, + {2, [3]byte{0xd0, 0xb3, 0x00}}, {2, [3]byte{0xd0, 0x93, 0x00}}, + {2, [3]byte{0xc2, 0xab, 0x00}}, {2, [3]byte{0xc2, 0xbb, 0x00}}, + {3, [3]byte{0xe2, 0x96, 0x91}}, {3, [3]byte{0xe2, 0x96, 0x92}}, + {3, [3]byte{0xe2, 0x96, 0x93}}, {3, [3]byte{0xe2, 0x94, 0x82}}, + {3, [3]byte{0xe2, 0x94, 0xa4}}, {2, [3]byte{0xd1, 0x85, 0x00}}, + {2, [3]byte{0xd0, 0xa5, 0x00}}, {2, [3]byte{0xd0, 0xb8, 0x00}}, + {2, [3]byte{0xd0, 0x98, 0x00}}, {3, [3]byte{0xe2, 0x95, 0xa3}}, + {3, [3]byte{0xe2, 0x95, 0x91}}, {3, [3]byte{0xe2, 0x95, 0x97}}, + {3, [3]byte{0xe2, 0x95, 0x9d}}, {2, [3]byte{0xd0, 0xb9, 0x00}}, + {2, [3]byte{0xd0, 0x99, 0x00}}, {3, [3]byte{0xe2, 0x94, 0x90}}, + {3, [3]byte{0xe2, 0x94, 0x94}}, {3, [3]byte{0xe2, 0x94, 0xb4}}, + {3, [3]byte{0xe2, 0x94, 0xac}}, {3, [3]byte{0xe2, 0x94, 0x9c}}, + {3, [3]byte{0xe2, 0x94, 0x80}}, {3, [3]byte{0xe2, 0x94, 0xbc}}, + {2, [3]byte{0xd0, 0xba, 0x00}}, {2, [3]byte{0xd0, 0x9a, 0x00}}, + {3, [3]byte{0xe2, 0x95, 0x9a}}, {3, [3]byte{0xe2, 0x95, 0x94}}, + {3, [3]byte{0xe2, 0x95, 0xa9}}, {3, [3]byte{0xe2, 0x95, 0xa6}}, + {3, [3]byte{0xe2, 0x95, 0xa0}}, {3, [3]byte{0xe2, 0x95, 0x90}}, + {3, [3]byte{0xe2, 0x95, 0xac}}, {2, [3]byte{0xc2, 0xa4, 0x00}}, + {2, [3]byte{0xd0, 0xbb, 0x00}}, {2, [3]byte{0xd0, 0x9b, 0x00}}, + {2, [3]byte{0xd0, 0xbc, 0x00}}, {2, [3]byte{0xd0, 0x9c, 0x00}}, + {2, [3]byte{0xd0, 0xbd, 0x00}}, {2, [3]byte{0xd0, 0x9d, 0x00}}, + {2, [3]byte{0xd0, 0xbe, 0x00}}, {2, [3]byte{0xd0, 0x9e, 0x00}}, + {2, [3]byte{0xd0, 0xbf, 0x00}}, {3, [3]byte{0xe2, 0x94, 0x98}}, + {3, [3]byte{0xe2, 0x94, 0x8c}}, {3, [3]byte{0xe2, 0x96, 0x88}}, + {3, [3]byte{0xe2, 0x96, 0x84}}, {2, [3]byte{0xd0, 0x9f, 0x00}}, + {2, [3]byte{0xd1, 0x8f, 0x00}}, {3, [3]byte{0xe2, 0x96, 0x80}}, + {2, [3]byte{0xd0, 0xaf, 0x00}}, {2, [3]byte{0xd1, 0x80, 0x00}}, + {2, [3]byte{0xd0, 0xa0, 0x00}}, {2, [3]byte{0xd1, 0x81, 0x00}}, + {2, [3]byte{0xd0, 0xa1, 0x00}}, {2, [3]byte{0xd1, 0x82, 0x00}}, + {2, [3]byte{0xd0, 0xa2, 0x00}}, {2, [3]byte{0xd1, 0x83, 0x00}}, + {2, [3]byte{0xd0, 0xa3, 0x00}}, {2, [3]byte{0xd0, 0xb6, 0x00}}, + {2, [3]byte{0xd0, 0x96, 0x00}}, {2, [3]byte{0xd0, 0xb2, 0x00}}, + {2, [3]byte{0xd0, 0x92, 0x00}}, {2, [3]byte{0xd1, 0x8c, 0x00}}, + {2, [3]byte{0xd0, 0xac, 0x00}}, {3, [3]byte{0xe2, 0x84, 0x96}}, + {2, [3]byte{0xc2, 0xad, 0x00}}, {2, [3]byte{0xd1, 0x8b, 0x00}}, + {2, [3]byte{0xd0, 0xab, 0x00}}, {2, [3]byte{0xd0, 0xb7, 0x00}}, + {2, [3]byte{0xd0, 0x97, 0x00}}, {2, [3]byte{0xd1, 0x88, 0x00}}, + {2, [3]byte{0xd0, 0xa8, 0x00}}, {2, [3]byte{0xd1, 0x8d, 0x00}}, + {2, [3]byte{0xd0, 0xad, 0x00}}, {2, [3]byte{0xd1, 0x89, 0x00}}, + {2, [3]byte{0xd0, 0xa9, 0x00}}, {2, [3]byte{0xd1, 0x87, 0x00}}, + {2, [3]byte{0xd0, 0xa7, 0x00}}, {2, [3]byte{0xc2, 0xa7, 0x00}}, + {3, [3]byte{0xe2, 0x96, 0xa0}}, {2, [3]byte{0xc2, 0xa0, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xff0000a0, 0xcf0000a4, 0xfd0000a7, 0xae0000ab, 0xf00000ad, 0xaf0000bb, 0x85000401, 0x81000402, + 0x83000403, 0x87000404, 0x89000405, 0x8b000406, 0x8d000407, 0x8f000408, 0x91000409, 0x9300040a, + 0x9500040b, 0x9700040c, 0x9900040e, 0x9b00040f, 0xa1000410, 0xa3000411, 0xec000412, 0xad000413, + 0xa7000414, 0xa9000415, 0xea000416, 0xf4000417, 0xb8000418, 0xbe000419, 0xc700041a, 0xd100041b, + 0xd300041c, 0xd500041d, 0xd700041e, 0xdd00041f, 0xe2000420, 0xe4000421, 0xe6000422, 0xe8000423, + 0xab000424, 0xb6000425, 0xa5000426, 0xfc000427, 0xf6000428, 0xfa000429, 0x9f00042a, 0xf200042b, + 0xee00042c, 0xf800042d, 0x9d00042e, 0xe000042f, 0xa0000430, 0xa2000431, 0xeb000432, 0xac000433, + 0xa6000434, 0xa8000435, 0xe9000436, 0xf3000437, 0xb7000438, 0xbd000439, 0xc600043a, 0xd000043b, + 0xd200043c, 0xd400043d, 0xd600043e, 0xd800043f, 0xe1000440, 0xe3000441, 0xe5000442, 0xe7000443, + 0xaa000444, 0xb5000445, 0xa4000446, 0xfb000447, 0xf5000448, 0xf9000449, 0x9e00044a, 0xf100044b, + 0xed00044c, 0xf700044d, 0x9c00044e, 0xde00044f, 0x84000451, 0x80000452, 0x82000453, 0x86000454, + 0x88000455, 0x8a000456, 0x8c000457, 0x8e000458, 0x90000459, 0x9200045a, 0x9400045b, 0x9600045c, + 0x9800045e, 0x9a00045f, 0xef002116, 0xc4002500, 0xb3002502, 0xda00250c, 0xbf002510, 0xc0002514, + 0xd9002518, 0xc300251c, 0xb4002524, 0xc200252c, 0xc1002534, 0xc500253c, 0xcd002550, 0xba002551, + 0xc9002554, 0xbb002557, 0xc800255a, 0xbc00255d, 0xcc002560, 0xb9002563, 0xcb002566, 0xca002569, + 0xce00256c, 0xdf002580, 0xdc002584, 0xdb002588, 0xb0002591, 0xb1002592, 0xb2002593, 0xfe0025a0, + }, +} + +// CodePage858 is the Windows Code Page 858 encoding. +var CodePage858 *Charmap = &codePage858 + +var codePage858 = Charmap{ + name: "Windows Code Page 858", + mib: identifier.IBM00858, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {2, [3]byte{0xc3, 0x87, 0x00}}, {2, [3]byte{0xc3, 0xbc, 0x00}}, + {2, [3]byte{0xc3, 0xa9, 0x00}}, {2, [3]byte{0xc3, 0xa2, 0x00}}, + {2, [3]byte{0xc3, 0xa4, 0x00}}, {2, [3]byte{0xc3, 0xa0, 0x00}}, + {2, [3]byte{0xc3, 0xa5, 0x00}}, {2, [3]byte{0xc3, 0xa7, 0x00}}, + {2, [3]byte{0xc3, 0xaa, 0x00}}, {2, [3]byte{0xc3, 0xab, 0x00}}, + {2, [3]byte{0xc3, 0xa8, 0x00}}, {2, [3]byte{0xc3, 0xaf, 0x00}}, + {2, [3]byte{0xc3, 0xae, 0x00}}, {2, [3]byte{0xc3, 0xac, 0x00}}, + {2, [3]byte{0xc3, 0x84, 0x00}}, {2, [3]byte{0xc3, 0x85, 0x00}}, + {2, [3]byte{0xc3, 0x89, 0x00}}, {2, [3]byte{0xc3, 0xa6, 0x00}}, + {2, [3]byte{0xc3, 0x86, 0x00}}, {2, [3]byte{0xc3, 0xb4, 0x00}}, + {2, [3]byte{0xc3, 0xb6, 0x00}}, {2, [3]byte{0xc3, 0xb2, 0x00}}, + {2, [3]byte{0xc3, 0xbb, 0x00}}, {2, [3]byte{0xc3, 0xb9, 0x00}}, + {2, [3]byte{0xc3, 0xbf, 0x00}}, {2, [3]byte{0xc3, 0x96, 0x00}}, + {2, [3]byte{0xc3, 0x9c, 0x00}}, {2, [3]byte{0xc3, 0xb8, 0x00}}, + {2, [3]byte{0xc2, 0xa3, 0x00}}, {2, [3]byte{0xc3, 0x98, 0x00}}, + {2, [3]byte{0xc3, 0x97, 0x00}}, {2, [3]byte{0xc6, 0x92, 0x00}}, + {2, [3]byte{0xc3, 0xa1, 0x00}}, {2, [3]byte{0xc3, 0xad, 0x00}}, + {2, [3]byte{0xc3, 0xb3, 0x00}}, {2, [3]byte{0xc3, 0xba, 0x00}}, + {2, [3]byte{0xc3, 0xb1, 0x00}}, {2, [3]byte{0xc3, 0x91, 0x00}}, + {2, [3]byte{0xc2, 0xaa, 0x00}}, {2, [3]byte{0xc2, 0xba, 0x00}}, + {2, [3]byte{0xc2, 0xbf, 0x00}}, {2, [3]byte{0xc2, 0xae, 0x00}}, + {2, [3]byte{0xc2, 0xac, 0x00}}, {2, [3]byte{0xc2, 0xbd, 0x00}}, + {2, [3]byte{0xc2, 0xbc, 0x00}}, {2, [3]byte{0xc2, 0xa1, 0x00}}, + {2, [3]byte{0xc2, 0xab, 0x00}}, {2, [3]byte{0xc2, 0xbb, 0x00}}, + {3, [3]byte{0xe2, 0x96, 0x91}}, {3, [3]byte{0xe2, 0x96, 0x92}}, + {3, [3]byte{0xe2, 0x96, 0x93}}, {3, [3]byte{0xe2, 0x94, 0x82}}, + {3, [3]byte{0xe2, 0x94, 0xa4}}, {2, [3]byte{0xc3, 0x81, 0x00}}, + {2, [3]byte{0xc3, 0x82, 0x00}}, {2, [3]byte{0xc3, 0x80, 0x00}}, + {2, [3]byte{0xc2, 0xa9, 0x00}}, {3, [3]byte{0xe2, 0x95, 0xa3}}, + {3, [3]byte{0xe2, 0x95, 0x91}}, {3, [3]byte{0xe2, 0x95, 0x97}}, + {3, [3]byte{0xe2, 0x95, 0x9d}}, {2, [3]byte{0xc2, 0xa2, 0x00}}, + {2, [3]byte{0xc2, 0xa5, 0x00}}, {3, [3]byte{0xe2, 0x94, 0x90}}, + {3, [3]byte{0xe2, 0x94, 0x94}}, {3, [3]byte{0xe2, 0x94, 0xb4}}, + {3, [3]byte{0xe2, 0x94, 0xac}}, {3, [3]byte{0xe2, 0x94, 0x9c}}, + {3, [3]byte{0xe2, 0x94, 0x80}}, {3, [3]byte{0xe2, 0x94, 0xbc}}, + {2, [3]byte{0xc3, 0xa3, 0x00}}, {2, [3]byte{0xc3, 0x83, 0x00}}, + {3, [3]byte{0xe2, 0x95, 0x9a}}, {3, [3]byte{0xe2, 0x95, 0x94}}, + {3, [3]byte{0xe2, 0x95, 0xa9}}, {3, [3]byte{0xe2, 0x95, 0xa6}}, + {3, [3]byte{0xe2, 0x95, 0xa0}}, {3, [3]byte{0xe2, 0x95, 0x90}}, + {3, [3]byte{0xe2, 0x95, 0xac}}, {2, [3]byte{0xc2, 0xa4, 0x00}}, + {2, [3]byte{0xc3, 0xb0, 0x00}}, {2, [3]byte{0xc3, 0x90, 0x00}}, + {2, [3]byte{0xc3, 0x8a, 0x00}}, {2, [3]byte{0xc3, 0x8b, 0x00}}, + {2, [3]byte{0xc3, 0x88, 0x00}}, {3, [3]byte{0xe2, 0x82, 0xac}}, + {2, [3]byte{0xc3, 0x8d, 0x00}}, {2, [3]byte{0xc3, 0x8e, 0x00}}, + {2, [3]byte{0xc3, 0x8f, 0x00}}, {3, [3]byte{0xe2, 0x94, 0x98}}, + {3, [3]byte{0xe2, 0x94, 0x8c}}, {3, [3]byte{0xe2, 0x96, 0x88}}, + {3, [3]byte{0xe2, 0x96, 0x84}}, {2, [3]byte{0xc2, 0xa6, 0x00}}, + {2, [3]byte{0xc3, 0x8c, 0x00}}, {3, [3]byte{0xe2, 0x96, 0x80}}, + {2, [3]byte{0xc3, 0x93, 0x00}}, {2, [3]byte{0xc3, 0x9f, 0x00}}, + {2, [3]byte{0xc3, 0x94, 0x00}}, {2, [3]byte{0xc3, 0x92, 0x00}}, + {2, [3]byte{0xc3, 0xb5, 0x00}}, {2, [3]byte{0xc3, 0x95, 0x00}}, + {2, [3]byte{0xc2, 0xb5, 0x00}}, {2, [3]byte{0xc3, 0xbe, 0x00}}, + {2, [3]byte{0xc3, 0x9e, 0x00}}, {2, [3]byte{0xc3, 0x9a, 0x00}}, + {2, [3]byte{0xc3, 0x9b, 0x00}}, {2, [3]byte{0xc3, 0x99, 0x00}}, + {2, [3]byte{0xc3, 0xbd, 0x00}}, {2, [3]byte{0xc3, 0x9d, 0x00}}, + {2, [3]byte{0xc2, 0xaf, 0x00}}, {2, [3]byte{0xc2, 0xb4, 0x00}}, + {2, [3]byte{0xc2, 0xad, 0x00}}, {2, [3]byte{0xc2, 0xb1, 0x00}}, + {3, [3]byte{0xe2, 0x80, 0x97}}, {2, [3]byte{0xc2, 0xbe, 0x00}}, + {2, [3]byte{0xc2, 0xb6, 0x00}}, {2, [3]byte{0xc2, 0xa7, 0x00}}, + {2, [3]byte{0xc3, 0xb7, 0x00}}, {2, [3]byte{0xc2, 0xb8, 0x00}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {2, [3]byte{0xc2, 0xa8, 0x00}}, + {2, [3]byte{0xc2, 0xb7, 0x00}}, {2, [3]byte{0xc2, 0xb9, 0x00}}, + {2, [3]byte{0xc2, 0xb3, 0x00}}, {2, [3]byte{0xc2, 0xb2, 0x00}}, + {3, [3]byte{0xe2, 0x96, 0xa0}}, {2, [3]byte{0xc2, 0xa0, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xff0000a0, 0xad0000a1, 0xbd0000a2, 0x9c0000a3, 0xcf0000a4, 0xbe0000a5, 0xdd0000a6, 0xf50000a7, + 0xf90000a8, 0xb80000a9, 0xa60000aa, 0xae0000ab, 0xaa0000ac, 0xf00000ad, 0xa90000ae, 0xee0000af, + 0xf80000b0, 0xf10000b1, 0xfd0000b2, 0xfc0000b3, 0xef0000b4, 0xe60000b5, 0xf40000b6, 0xfa0000b7, + 0xf70000b8, 0xfb0000b9, 0xa70000ba, 0xaf0000bb, 0xac0000bc, 0xab0000bd, 0xf30000be, 0xa80000bf, + 0xb70000c0, 0xb50000c1, 0xb60000c2, 0xc70000c3, 0x8e0000c4, 0x8f0000c5, 0x920000c6, 0x800000c7, + 0xd40000c8, 0x900000c9, 0xd20000ca, 0xd30000cb, 0xde0000cc, 0xd60000cd, 0xd70000ce, 0xd80000cf, + 0xd10000d0, 0xa50000d1, 0xe30000d2, 0xe00000d3, 0xe20000d4, 0xe50000d5, 0x990000d6, 0x9e0000d7, + 0x9d0000d8, 0xeb0000d9, 0xe90000da, 0xea0000db, 0x9a0000dc, 0xed0000dd, 0xe80000de, 0xe10000df, + 0x850000e0, 0xa00000e1, 0x830000e2, 0xc60000e3, 0x840000e4, 0x860000e5, 0x910000e6, 0x870000e7, + 0x8a0000e8, 0x820000e9, 0x880000ea, 0x890000eb, 0x8d0000ec, 0xa10000ed, 0x8c0000ee, 0x8b0000ef, + 0xd00000f0, 0xa40000f1, 0x950000f2, 0xa20000f3, 0x930000f4, 0xe40000f5, 0x940000f6, 0xf60000f7, + 0x9b0000f8, 0x970000f9, 0xa30000fa, 0x960000fb, 0x810000fc, 0xec0000fd, 0xe70000fe, 0x980000ff, + 0x9f000192, 0xf2002017, 0xd50020ac, 0xc4002500, 0xb3002502, 0xda00250c, 0xbf002510, 0xc0002514, + 0xd9002518, 0xc300251c, 0xb4002524, 0xc200252c, 0xc1002534, 0xc500253c, 0xcd002550, 0xba002551, + 0xc9002554, 0xbb002557, 0xc800255a, 0xbc00255d, 0xcc002560, 0xb9002563, 0xcb002566, 0xca002569, + 0xce00256c, 0xdf002580, 0xdc002584, 0xdb002588, 0xb0002591, 0xb1002592, 0xb2002593, 0xfe0025a0, + }, +} + +// CodePage860 is the IBM Code Page 860 encoding. +var CodePage860 *Charmap = &codePage860 + +var codePage860 = Charmap{ + name: "IBM Code Page 860", + mib: identifier.IBM860, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {2, [3]byte{0xc3, 0x87, 0x00}}, {2, [3]byte{0xc3, 0xbc, 0x00}}, + {2, [3]byte{0xc3, 0xa9, 0x00}}, {2, [3]byte{0xc3, 0xa2, 0x00}}, + {2, [3]byte{0xc3, 0xa3, 0x00}}, {2, [3]byte{0xc3, 0xa0, 0x00}}, + {2, [3]byte{0xc3, 0x81, 0x00}}, {2, [3]byte{0xc3, 0xa7, 0x00}}, + {2, [3]byte{0xc3, 0xaa, 0x00}}, {2, [3]byte{0xc3, 0x8a, 0x00}}, + {2, [3]byte{0xc3, 0xa8, 0x00}}, {2, [3]byte{0xc3, 0x8d, 0x00}}, + {2, [3]byte{0xc3, 0x94, 0x00}}, {2, [3]byte{0xc3, 0xac, 0x00}}, + {2, [3]byte{0xc3, 0x83, 0x00}}, {2, [3]byte{0xc3, 0x82, 0x00}}, + {2, [3]byte{0xc3, 0x89, 0x00}}, {2, [3]byte{0xc3, 0x80, 0x00}}, + {2, [3]byte{0xc3, 0x88, 0x00}}, {2, [3]byte{0xc3, 0xb4, 0x00}}, + {2, [3]byte{0xc3, 0xb5, 0x00}}, {2, [3]byte{0xc3, 0xb2, 0x00}}, + {2, [3]byte{0xc3, 0x9a, 0x00}}, {2, [3]byte{0xc3, 0xb9, 0x00}}, + {2, [3]byte{0xc3, 0x8c, 0x00}}, {2, [3]byte{0xc3, 0x95, 0x00}}, + {2, [3]byte{0xc3, 0x9c, 0x00}}, {2, [3]byte{0xc2, 0xa2, 0x00}}, + {2, [3]byte{0xc2, 0xa3, 0x00}}, {2, [3]byte{0xc3, 0x99, 0x00}}, + {3, [3]byte{0xe2, 0x82, 0xa7}}, {2, [3]byte{0xc3, 0x93, 0x00}}, + {2, [3]byte{0xc3, 0xa1, 0x00}}, {2, [3]byte{0xc3, 0xad, 0x00}}, + {2, [3]byte{0xc3, 0xb3, 0x00}}, {2, [3]byte{0xc3, 0xba, 0x00}}, + {2, [3]byte{0xc3, 0xb1, 0x00}}, {2, [3]byte{0xc3, 0x91, 0x00}}, + {2, [3]byte{0xc2, 0xaa, 0x00}}, {2, [3]byte{0xc2, 0xba, 0x00}}, + {2, [3]byte{0xc2, 0xbf, 0x00}}, {2, [3]byte{0xc3, 0x92, 0x00}}, + {2, [3]byte{0xc2, 0xac, 0x00}}, {2, [3]byte{0xc2, 0xbd, 0x00}}, + {2, [3]byte{0xc2, 0xbc, 0x00}}, {2, [3]byte{0xc2, 0xa1, 0x00}}, + {2, [3]byte{0xc2, 0xab, 0x00}}, {2, [3]byte{0xc2, 0xbb, 0x00}}, + {3, [3]byte{0xe2, 0x96, 0x91}}, {3, [3]byte{0xe2, 0x96, 0x92}}, + {3, [3]byte{0xe2, 0x96, 0x93}}, {3, [3]byte{0xe2, 0x94, 0x82}}, + {3, [3]byte{0xe2, 0x94, 0xa4}}, {3, [3]byte{0xe2, 0x95, 0xa1}}, + {3, [3]byte{0xe2, 0x95, 0xa2}}, {3, [3]byte{0xe2, 0x95, 0x96}}, + {3, [3]byte{0xe2, 0x95, 0x95}}, {3, [3]byte{0xe2, 0x95, 0xa3}}, + {3, [3]byte{0xe2, 0x95, 0x91}}, {3, [3]byte{0xe2, 0x95, 0x97}}, + {3, [3]byte{0xe2, 0x95, 0x9d}}, {3, [3]byte{0xe2, 0x95, 0x9c}}, + {3, [3]byte{0xe2, 0x95, 0x9b}}, {3, [3]byte{0xe2, 0x94, 0x90}}, + {3, [3]byte{0xe2, 0x94, 0x94}}, {3, [3]byte{0xe2, 0x94, 0xb4}}, + {3, [3]byte{0xe2, 0x94, 0xac}}, {3, [3]byte{0xe2, 0x94, 0x9c}}, + {3, [3]byte{0xe2, 0x94, 0x80}}, {3, [3]byte{0xe2, 0x94, 0xbc}}, + {3, [3]byte{0xe2, 0x95, 0x9e}}, {3, [3]byte{0xe2, 0x95, 0x9f}}, + {3, [3]byte{0xe2, 0x95, 0x9a}}, {3, [3]byte{0xe2, 0x95, 0x94}}, + {3, [3]byte{0xe2, 0x95, 0xa9}}, {3, [3]byte{0xe2, 0x95, 0xa6}}, + {3, [3]byte{0xe2, 0x95, 0xa0}}, {3, [3]byte{0xe2, 0x95, 0x90}}, + {3, [3]byte{0xe2, 0x95, 0xac}}, {3, [3]byte{0xe2, 0x95, 0xa7}}, + {3, [3]byte{0xe2, 0x95, 0xa8}}, {3, [3]byte{0xe2, 0x95, 0xa4}}, + {3, [3]byte{0xe2, 0x95, 0xa5}}, {3, [3]byte{0xe2, 0x95, 0x99}}, + {3, [3]byte{0xe2, 0x95, 0x98}}, {3, [3]byte{0xe2, 0x95, 0x92}}, + {3, [3]byte{0xe2, 0x95, 0x93}}, {3, [3]byte{0xe2, 0x95, 0xab}}, + {3, [3]byte{0xe2, 0x95, 0xaa}}, {3, [3]byte{0xe2, 0x94, 0x98}}, + {3, [3]byte{0xe2, 0x94, 0x8c}}, {3, [3]byte{0xe2, 0x96, 0x88}}, + {3, [3]byte{0xe2, 0x96, 0x84}}, {3, [3]byte{0xe2, 0x96, 0x8c}}, + {3, [3]byte{0xe2, 0x96, 0x90}}, {3, [3]byte{0xe2, 0x96, 0x80}}, + {2, [3]byte{0xce, 0xb1, 0x00}}, {2, [3]byte{0xc3, 0x9f, 0x00}}, + {2, [3]byte{0xce, 0x93, 0x00}}, {2, [3]byte{0xcf, 0x80, 0x00}}, + {2, [3]byte{0xce, 0xa3, 0x00}}, {2, [3]byte{0xcf, 0x83, 0x00}}, + {2, [3]byte{0xc2, 0xb5, 0x00}}, {2, [3]byte{0xcf, 0x84, 0x00}}, + {2, [3]byte{0xce, 0xa6, 0x00}}, {2, [3]byte{0xce, 0x98, 0x00}}, + {2, [3]byte{0xce, 0xa9, 0x00}}, {2, [3]byte{0xce, 0xb4, 0x00}}, + {3, [3]byte{0xe2, 0x88, 0x9e}}, {2, [3]byte{0xcf, 0x86, 0x00}}, + {2, [3]byte{0xce, 0xb5, 0x00}}, {3, [3]byte{0xe2, 0x88, 0xa9}}, + {3, [3]byte{0xe2, 0x89, 0xa1}}, {2, [3]byte{0xc2, 0xb1, 0x00}}, + {3, [3]byte{0xe2, 0x89, 0xa5}}, {3, [3]byte{0xe2, 0x89, 0xa4}}, + {3, [3]byte{0xe2, 0x8c, 0xa0}}, {3, [3]byte{0xe2, 0x8c, 0xa1}}, + {2, [3]byte{0xc3, 0xb7, 0x00}}, {3, [3]byte{0xe2, 0x89, 0x88}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {3, [3]byte{0xe2, 0x88, 0x99}}, + {2, [3]byte{0xc2, 0xb7, 0x00}}, {3, [3]byte{0xe2, 0x88, 0x9a}}, + {3, [3]byte{0xe2, 0x81, 0xbf}}, {2, [3]byte{0xc2, 0xb2, 0x00}}, + {3, [3]byte{0xe2, 0x96, 0xa0}}, {2, [3]byte{0xc2, 0xa0, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xff0000a0, 0xad0000a1, 0x9b0000a2, 0x9c0000a3, 0xa60000aa, 0xae0000ab, 0xaa0000ac, 0xf80000b0, + 0xf10000b1, 0xfd0000b2, 0xe60000b5, 0xfa0000b7, 0xa70000ba, 0xaf0000bb, 0xac0000bc, 0xab0000bd, + 0xa80000bf, 0x910000c0, 0x860000c1, 0x8f0000c2, 0x8e0000c3, 0x800000c7, 0x920000c8, 0x900000c9, + 0x890000ca, 0x980000cc, 0x8b0000cd, 0xa50000d1, 0xa90000d2, 0x9f0000d3, 0x8c0000d4, 0x990000d5, + 0x9d0000d9, 0x960000da, 0x9a0000dc, 0xe10000df, 0x850000e0, 0xa00000e1, 0x830000e2, 0x840000e3, + 0x870000e7, 0x8a0000e8, 0x820000e9, 0x880000ea, 0x8d0000ec, 0xa10000ed, 0xa40000f1, 0x950000f2, + 0xa20000f3, 0x930000f4, 0x940000f5, 0xf60000f7, 0x970000f9, 0xa30000fa, 0x810000fc, 0xe2000393, + 0xe9000398, 0xe40003a3, 0xe80003a6, 0xea0003a9, 0xe00003b1, 0xeb0003b4, 0xee0003b5, 0xe30003c0, + 0xe50003c3, 0xe70003c4, 0xed0003c6, 0xfc00207f, 0x9e0020a7, 0xf9002219, 0xfb00221a, 0xec00221e, + 0xef002229, 0xf7002248, 0xf0002261, 0xf3002264, 0xf2002265, 0xf4002320, 0xf5002321, 0xc4002500, + 0xb3002502, 0xda00250c, 0xbf002510, 0xc0002514, 0xd9002518, 0xc300251c, 0xb4002524, 0xc200252c, + 0xc1002534, 0xc500253c, 0xcd002550, 0xba002551, 0xd5002552, 0xd6002553, 0xc9002554, 0xb8002555, + 0xb7002556, 0xbb002557, 0xd4002558, 0xd3002559, 0xc800255a, 0xbe00255b, 0xbd00255c, 0xbc00255d, + 0xc600255e, 0xc700255f, 0xcc002560, 0xb5002561, 0xb6002562, 0xb9002563, 0xd1002564, 0xd2002565, + 0xcb002566, 0xcf002567, 0xd0002568, 0xca002569, 0xd800256a, 0xd700256b, 0xce00256c, 0xdf002580, + 0xdc002584, 0xdb002588, 0xdd00258c, 0xde002590, 0xb0002591, 0xb1002592, 0xb2002593, 0xfe0025a0, + }, +} + +// CodePage862 is the IBM Code Page 862 encoding. +var CodePage862 *Charmap = &codePage862 + +var codePage862 = Charmap{ + name: "IBM Code Page 862", + mib: identifier.PC862LatinHebrew, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {2, [3]byte{0xd7, 0x90, 0x00}}, {2, [3]byte{0xd7, 0x91, 0x00}}, + {2, [3]byte{0xd7, 0x92, 0x00}}, {2, [3]byte{0xd7, 0x93, 0x00}}, + {2, [3]byte{0xd7, 0x94, 0x00}}, {2, [3]byte{0xd7, 0x95, 0x00}}, + {2, [3]byte{0xd7, 0x96, 0x00}}, {2, [3]byte{0xd7, 0x97, 0x00}}, + {2, [3]byte{0xd7, 0x98, 0x00}}, {2, [3]byte{0xd7, 0x99, 0x00}}, + {2, [3]byte{0xd7, 0x9a, 0x00}}, {2, [3]byte{0xd7, 0x9b, 0x00}}, + {2, [3]byte{0xd7, 0x9c, 0x00}}, {2, [3]byte{0xd7, 0x9d, 0x00}}, + {2, [3]byte{0xd7, 0x9e, 0x00}}, {2, [3]byte{0xd7, 0x9f, 0x00}}, + {2, [3]byte{0xd7, 0xa0, 0x00}}, {2, [3]byte{0xd7, 0xa1, 0x00}}, + {2, [3]byte{0xd7, 0xa2, 0x00}}, {2, [3]byte{0xd7, 0xa3, 0x00}}, + {2, [3]byte{0xd7, 0xa4, 0x00}}, {2, [3]byte{0xd7, 0xa5, 0x00}}, + {2, [3]byte{0xd7, 0xa6, 0x00}}, {2, [3]byte{0xd7, 0xa7, 0x00}}, + {2, [3]byte{0xd7, 0xa8, 0x00}}, {2, [3]byte{0xd7, 0xa9, 0x00}}, + {2, [3]byte{0xd7, 0xaa, 0x00}}, {2, [3]byte{0xc2, 0xa2, 0x00}}, + {2, [3]byte{0xc2, 0xa3, 0x00}}, {2, [3]byte{0xc2, 0xa5, 0x00}}, + {3, [3]byte{0xe2, 0x82, 0xa7}}, {2, [3]byte{0xc6, 0x92, 0x00}}, + {2, [3]byte{0xc3, 0xa1, 0x00}}, {2, [3]byte{0xc3, 0xad, 0x00}}, + {2, [3]byte{0xc3, 0xb3, 0x00}}, {2, [3]byte{0xc3, 0xba, 0x00}}, + {2, [3]byte{0xc3, 0xb1, 0x00}}, {2, [3]byte{0xc3, 0x91, 0x00}}, + {2, [3]byte{0xc2, 0xaa, 0x00}}, {2, [3]byte{0xc2, 0xba, 0x00}}, + {2, [3]byte{0xc2, 0xbf, 0x00}}, {3, [3]byte{0xe2, 0x8c, 0x90}}, + {2, [3]byte{0xc2, 0xac, 0x00}}, {2, [3]byte{0xc2, 0xbd, 0x00}}, + {2, [3]byte{0xc2, 0xbc, 0x00}}, {2, [3]byte{0xc2, 0xa1, 0x00}}, + {2, [3]byte{0xc2, 0xab, 0x00}}, {2, [3]byte{0xc2, 0xbb, 0x00}}, + {3, [3]byte{0xe2, 0x96, 0x91}}, {3, [3]byte{0xe2, 0x96, 0x92}}, + {3, [3]byte{0xe2, 0x96, 0x93}}, {3, [3]byte{0xe2, 0x94, 0x82}}, + {3, [3]byte{0xe2, 0x94, 0xa4}}, {3, [3]byte{0xe2, 0x95, 0xa1}}, + {3, [3]byte{0xe2, 0x95, 0xa2}}, {3, [3]byte{0xe2, 0x95, 0x96}}, + {3, [3]byte{0xe2, 0x95, 0x95}}, {3, [3]byte{0xe2, 0x95, 0xa3}}, + {3, [3]byte{0xe2, 0x95, 0x91}}, {3, [3]byte{0xe2, 0x95, 0x97}}, + {3, [3]byte{0xe2, 0x95, 0x9d}}, {3, [3]byte{0xe2, 0x95, 0x9c}}, + {3, [3]byte{0xe2, 0x95, 0x9b}}, {3, [3]byte{0xe2, 0x94, 0x90}}, + {3, [3]byte{0xe2, 0x94, 0x94}}, {3, [3]byte{0xe2, 0x94, 0xb4}}, + {3, [3]byte{0xe2, 0x94, 0xac}}, {3, [3]byte{0xe2, 0x94, 0x9c}}, + {3, [3]byte{0xe2, 0x94, 0x80}}, {3, [3]byte{0xe2, 0x94, 0xbc}}, + {3, [3]byte{0xe2, 0x95, 0x9e}}, {3, [3]byte{0xe2, 0x95, 0x9f}}, + {3, [3]byte{0xe2, 0x95, 0x9a}}, {3, [3]byte{0xe2, 0x95, 0x94}}, + {3, [3]byte{0xe2, 0x95, 0xa9}}, {3, [3]byte{0xe2, 0x95, 0xa6}}, + {3, [3]byte{0xe2, 0x95, 0xa0}}, {3, [3]byte{0xe2, 0x95, 0x90}}, + {3, [3]byte{0xe2, 0x95, 0xac}}, {3, [3]byte{0xe2, 0x95, 0xa7}}, + {3, [3]byte{0xe2, 0x95, 0xa8}}, {3, [3]byte{0xe2, 0x95, 0xa4}}, + {3, [3]byte{0xe2, 0x95, 0xa5}}, {3, [3]byte{0xe2, 0x95, 0x99}}, + {3, [3]byte{0xe2, 0x95, 0x98}}, {3, [3]byte{0xe2, 0x95, 0x92}}, + {3, [3]byte{0xe2, 0x95, 0x93}}, {3, [3]byte{0xe2, 0x95, 0xab}}, + {3, [3]byte{0xe2, 0x95, 0xaa}}, {3, [3]byte{0xe2, 0x94, 0x98}}, + {3, [3]byte{0xe2, 0x94, 0x8c}}, {3, [3]byte{0xe2, 0x96, 0x88}}, + {3, [3]byte{0xe2, 0x96, 0x84}}, {3, [3]byte{0xe2, 0x96, 0x8c}}, + {3, [3]byte{0xe2, 0x96, 0x90}}, {3, [3]byte{0xe2, 0x96, 0x80}}, + {2, [3]byte{0xce, 0xb1, 0x00}}, {2, [3]byte{0xc3, 0x9f, 0x00}}, + {2, [3]byte{0xce, 0x93, 0x00}}, {2, [3]byte{0xcf, 0x80, 0x00}}, + {2, [3]byte{0xce, 0xa3, 0x00}}, {2, [3]byte{0xcf, 0x83, 0x00}}, + {2, [3]byte{0xc2, 0xb5, 0x00}}, {2, [3]byte{0xcf, 0x84, 0x00}}, + {2, [3]byte{0xce, 0xa6, 0x00}}, {2, [3]byte{0xce, 0x98, 0x00}}, + {2, [3]byte{0xce, 0xa9, 0x00}}, {2, [3]byte{0xce, 0xb4, 0x00}}, + {3, [3]byte{0xe2, 0x88, 0x9e}}, {2, [3]byte{0xcf, 0x86, 0x00}}, + {2, [3]byte{0xce, 0xb5, 0x00}}, {3, [3]byte{0xe2, 0x88, 0xa9}}, + {3, [3]byte{0xe2, 0x89, 0xa1}}, {2, [3]byte{0xc2, 0xb1, 0x00}}, + {3, [3]byte{0xe2, 0x89, 0xa5}}, {3, [3]byte{0xe2, 0x89, 0xa4}}, + {3, [3]byte{0xe2, 0x8c, 0xa0}}, {3, [3]byte{0xe2, 0x8c, 0xa1}}, + {2, [3]byte{0xc3, 0xb7, 0x00}}, {3, [3]byte{0xe2, 0x89, 0x88}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {3, [3]byte{0xe2, 0x88, 0x99}}, + {2, [3]byte{0xc2, 0xb7, 0x00}}, {3, [3]byte{0xe2, 0x88, 0x9a}}, + {3, [3]byte{0xe2, 0x81, 0xbf}}, {2, [3]byte{0xc2, 0xb2, 0x00}}, + {3, [3]byte{0xe2, 0x96, 0xa0}}, {2, [3]byte{0xc2, 0xa0, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xff0000a0, 0xad0000a1, 0x9b0000a2, 0x9c0000a3, 0x9d0000a5, 0xa60000aa, 0xae0000ab, 0xaa0000ac, + 0xf80000b0, 0xf10000b1, 0xfd0000b2, 0xe60000b5, 0xfa0000b7, 0xa70000ba, 0xaf0000bb, 0xac0000bc, + 0xab0000bd, 0xa80000bf, 0xa50000d1, 0xe10000df, 0xa00000e1, 0xa10000ed, 0xa40000f1, 0xa20000f3, + 0xf60000f7, 0xa30000fa, 0x9f000192, 0xe2000393, 0xe9000398, 0xe40003a3, 0xe80003a6, 0xea0003a9, + 0xe00003b1, 0xeb0003b4, 0xee0003b5, 0xe30003c0, 0xe50003c3, 0xe70003c4, 0xed0003c6, 0x800005d0, + 0x810005d1, 0x820005d2, 0x830005d3, 0x840005d4, 0x850005d5, 0x860005d6, 0x870005d7, 0x880005d8, + 0x890005d9, 0x8a0005da, 0x8b0005db, 0x8c0005dc, 0x8d0005dd, 0x8e0005de, 0x8f0005df, 0x900005e0, + 0x910005e1, 0x920005e2, 0x930005e3, 0x940005e4, 0x950005e5, 0x960005e6, 0x970005e7, 0x980005e8, + 0x990005e9, 0x9a0005ea, 0xfc00207f, 0x9e0020a7, 0xf9002219, 0xfb00221a, 0xec00221e, 0xef002229, + 0xf7002248, 0xf0002261, 0xf3002264, 0xf2002265, 0xa9002310, 0xf4002320, 0xf5002321, 0xc4002500, + 0xb3002502, 0xda00250c, 0xbf002510, 0xc0002514, 0xd9002518, 0xc300251c, 0xb4002524, 0xc200252c, + 0xc1002534, 0xc500253c, 0xcd002550, 0xba002551, 0xd5002552, 0xd6002553, 0xc9002554, 0xb8002555, + 0xb7002556, 0xbb002557, 0xd4002558, 0xd3002559, 0xc800255a, 0xbe00255b, 0xbd00255c, 0xbc00255d, + 0xc600255e, 0xc700255f, 0xcc002560, 0xb5002561, 0xb6002562, 0xb9002563, 0xd1002564, 0xd2002565, + 0xcb002566, 0xcf002567, 0xd0002568, 0xca002569, 0xd800256a, 0xd700256b, 0xce00256c, 0xdf002580, + 0xdc002584, 0xdb002588, 0xdd00258c, 0xde002590, 0xb0002591, 0xb1002592, 0xb2002593, 0xfe0025a0, + }, +} + +// CodePage863 is the IBM Code Page 863 encoding. +var CodePage863 *Charmap = &codePage863 + +var codePage863 = Charmap{ + name: "IBM Code Page 863", + mib: identifier.IBM863, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {2, [3]byte{0xc3, 0x87, 0x00}}, {2, [3]byte{0xc3, 0xbc, 0x00}}, + {2, [3]byte{0xc3, 0xa9, 0x00}}, {2, [3]byte{0xc3, 0xa2, 0x00}}, + {2, [3]byte{0xc3, 0x82, 0x00}}, {2, [3]byte{0xc3, 0xa0, 0x00}}, + {2, [3]byte{0xc2, 0xb6, 0x00}}, {2, [3]byte{0xc3, 0xa7, 0x00}}, + {2, [3]byte{0xc3, 0xaa, 0x00}}, {2, [3]byte{0xc3, 0xab, 0x00}}, + {2, [3]byte{0xc3, 0xa8, 0x00}}, {2, [3]byte{0xc3, 0xaf, 0x00}}, + {2, [3]byte{0xc3, 0xae, 0x00}}, {3, [3]byte{0xe2, 0x80, 0x97}}, + {2, [3]byte{0xc3, 0x80, 0x00}}, {2, [3]byte{0xc2, 0xa7, 0x00}}, + {2, [3]byte{0xc3, 0x89, 0x00}}, {2, [3]byte{0xc3, 0x88, 0x00}}, + {2, [3]byte{0xc3, 0x8a, 0x00}}, {2, [3]byte{0xc3, 0xb4, 0x00}}, + {2, [3]byte{0xc3, 0x8b, 0x00}}, {2, [3]byte{0xc3, 0x8f, 0x00}}, + {2, [3]byte{0xc3, 0xbb, 0x00}}, {2, [3]byte{0xc3, 0xb9, 0x00}}, + {2, [3]byte{0xc2, 0xa4, 0x00}}, {2, [3]byte{0xc3, 0x94, 0x00}}, + {2, [3]byte{0xc3, 0x9c, 0x00}}, {2, [3]byte{0xc2, 0xa2, 0x00}}, + {2, [3]byte{0xc2, 0xa3, 0x00}}, {2, [3]byte{0xc3, 0x99, 0x00}}, + {2, [3]byte{0xc3, 0x9b, 0x00}}, {2, [3]byte{0xc6, 0x92, 0x00}}, + {2, [3]byte{0xc2, 0xa6, 0x00}}, {2, [3]byte{0xc2, 0xb4, 0x00}}, + {2, [3]byte{0xc3, 0xb3, 0x00}}, {2, [3]byte{0xc3, 0xba, 0x00}}, + {2, [3]byte{0xc2, 0xa8, 0x00}}, {2, [3]byte{0xc2, 0xb8, 0x00}}, + {2, [3]byte{0xc2, 0xb3, 0x00}}, {2, [3]byte{0xc2, 0xaf, 0x00}}, + {2, [3]byte{0xc3, 0x8e, 0x00}}, {3, [3]byte{0xe2, 0x8c, 0x90}}, + {2, [3]byte{0xc2, 0xac, 0x00}}, {2, [3]byte{0xc2, 0xbd, 0x00}}, + {2, [3]byte{0xc2, 0xbc, 0x00}}, {2, [3]byte{0xc2, 0xbe, 0x00}}, + {2, [3]byte{0xc2, 0xab, 0x00}}, {2, [3]byte{0xc2, 0xbb, 0x00}}, + {3, [3]byte{0xe2, 0x96, 0x91}}, {3, [3]byte{0xe2, 0x96, 0x92}}, + {3, [3]byte{0xe2, 0x96, 0x93}}, {3, [3]byte{0xe2, 0x94, 0x82}}, + {3, [3]byte{0xe2, 0x94, 0xa4}}, {3, [3]byte{0xe2, 0x95, 0xa1}}, + {3, [3]byte{0xe2, 0x95, 0xa2}}, {3, [3]byte{0xe2, 0x95, 0x96}}, + {3, [3]byte{0xe2, 0x95, 0x95}}, {3, [3]byte{0xe2, 0x95, 0xa3}}, + {3, [3]byte{0xe2, 0x95, 0x91}}, {3, [3]byte{0xe2, 0x95, 0x97}}, + {3, [3]byte{0xe2, 0x95, 0x9d}}, {3, [3]byte{0xe2, 0x95, 0x9c}}, + {3, [3]byte{0xe2, 0x95, 0x9b}}, {3, [3]byte{0xe2, 0x94, 0x90}}, + {3, [3]byte{0xe2, 0x94, 0x94}}, {3, [3]byte{0xe2, 0x94, 0xb4}}, + {3, [3]byte{0xe2, 0x94, 0xac}}, {3, [3]byte{0xe2, 0x94, 0x9c}}, + {3, [3]byte{0xe2, 0x94, 0x80}}, {3, [3]byte{0xe2, 0x94, 0xbc}}, + {3, [3]byte{0xe2, 0x95, 0x9e}}, {3, [3]byte{0xe2, 0x95, 0x9f}}, + {3, [3]byte{0xe2, 0x95, 0x9a}}, {3, [3]byte{0xe2, 0x95, 0x94}}, + {3, [3]byte{0xe2, 0x95, 0xa9}}, {3, [3]byte{0xe2, 0x95, 0xa6}}, + {3, [3]byte{0xe2, 0x95, 0xa0}}, {3, [3]byte{0xe2, 0x95, 0x90}}, + {3, [3]byte{0xe2, 0x95, 0xac}}, {3, [3]byte{0xe2, 0x95, 0xa7}}, + {3, [3]byte{0xe2, 0x95, 0xa8}}, {3, [3]byte{0xe2, 0x95, 0xa4}}, + {3, [3]byte{0xe2, 0x95, 0xa5}}, {3, [3]byte{0xe2, 0x95, 0x99}}, + {3, [3]byte{0xe2, 0x95, 0x98}}, {3, [3]byte{0xe2, 0x95, 0x92}}, + {3, [3]byte{0xe2, 0x95, 0x93}}, {3, [3]byte{0xe2, 0x95, 0xab}}, + {3, [3]byte{0xe2, 0x95, 0xaa}}, {3, [3]byte{0xe2, 0x94, 0x98}}, + {3, [3]byte{0xe2, 0x94, 0x8c}}, {3, [3]byte{0xe2, 0x96, 0x88}}, + {3, [3]byte{0xe2, 0x96, 0x84}}, {3, [3]byte{0xe2, 0x96, 0x8c}}, + {3, [3]byte{0xe2, 0x96, 0x90}}, {3, [3]byte{0xe2, 0x96, 0x80}}, + {2, [3]byte{0xce, 0xb1, 0x00}}, {2, [3]byte{0xc3, 0x9f, 0x00}}, + {2, [3]byte{0xce, 0x93, 0x00}}, {2, [3]byte{0xcf, 0x80, 0x00}}, + {2, [3]byte{0xce, 0xa3, 0x00}}, {2, [3]byte{0xcf, 0x83, 0x00}}, + {2, [3]byte{0xc2, 0xb5, 0x00}}, {2, [3]byte{0xcf, 0x84, 0x00}}, + {2, [3]byte{0xce, 0xa6, 0x00}}, {2, [3]byte{0xce, 0x98, 0x00}}, + {2, [3]byte{0xce, 0xa9, 0x00}}, {2, [3]byte{0xce, 0xb4, 0x00}}, + {3, [3]byte{0xe2, 0x88, 0x9e}}, {2, [3]byte{0xcf, 0x86, 0x00}}, + {2, [3]byte{0xce, 0xb5, 0x00}}, {3, [3]byte{0xe2, 0x88, 0xa9}}, + {3, [3]byte{0xe2, 0x89, 0xa1}}, {2, [3]byte{0xc2, 0xb1, 0x00}}, + {3, [3]byte{0xe2, 0x89, 0xa5}}, {3, [3]byte{0xe2, 0x89, 0xa4}}, + {3, [3]byte{0xe2, 0x8c, 0xa0}}, {3, [3]byte{0xe2, 0x8c, 0xa1}}, + {2, [3]byte{0xc3, 0xb7, 0x00}}, {3, [3]byte{0xe2, 0x89, 0x88}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {3, [3]byte{0xe2, 0x88, 0x99}}, + {2, [3]byte{0xc2, 0xb7, 0x00}}, {3, [3]byte{0xe2, 0x88, 0x9a}}, + {3, [3]byte{0xe2, 0x81, 0xbf}}, {2, [3]byte{0xc2, 0xb2, 0x00}}, + {3, [3]byte{0xe2, 0x96, 0xa0}}, {2, [3]byte{0xc2, 0xa0, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xff0000a0, 0x9b0000a2, 0x9c0000a3, 0x980000a4, 0xa00000a6, 0x8f0000a7, 0xa40000a8, 0xae0000ab, + 0xaa0000ac, 0xa70000af, 0xf80000b0, 0xf10000b1, 0xfd0000b2, 0xa60000b3, 0xa10000b4, 0xe60000b5, + 0x860000b6, 0xfa0000b7, 0xa50000b8, 0xaf0000bb, 0xac0000bc, 0xab0000bd, 0xad0000be, 0x8e0000c0, + 0x840000c2, 0x800000c7, 0x910000c8, 0x900000c9, 0x920000ca, 0x940000cb, 0xa80000ce, 0x950000cf, + 0x990000d4, 0x9d0000d9, 0x9e0000db, 0x9a0000dc, 0xe10000df, 0x850000e0, 0x830000e2, 0x870000e7, + 0x8a0000e8, 0x820000e9, 0x880000ea, 0x890000eb, 0x8c0000ee, 0x8b0000ef, 0xa20000f3, 0x930000f4, + 0xf60000f7, 0x970000f9, 0xa30000fa, 0x960000fb, 0x810000fc, 0x9f000192, 0xe2000393, 0xe9000398, + 0xe40003a3, 0xe80003a6, 0xea0003a9, 0xe00003b1, 0xeb0003b4, 0xee0003b5, 0xe30003c0, 0xe50003c3, + 0xe70003c4, 0xed0003c6, 0x8d002017, 0xfc00207f, 0xf9002219, 0xfb00221a, 0xec00221e, 0xef002229, + 0xf7002248, 0xf0002261, 0xf3002264, 0xf2002265, 0xa9002310, 0xf4002320, 0xf5002321, 0xc4002500, + 0xb3002502, 0xda00250c, 0xbf002510, 0xc0002514, 0xd9002518, 0xc300251c, 0xb4002524, 0xc200252c, + 0xc1002534, 0xc500253c, 0xcd002550, 0xba002551, 0xd5002552, 0xd6002553, 0xc9002554, 0xb8002555, + 0xb7002556, 0xbb002557, 0xd4002558, 0xd3002559, 0xc800255a, 0xbe00255b, 0xbd00255c, 0xbc00255d, + 0xc600255e, 0xc700255f, 0xcc002560, 0xb5002561, 0xb6002562, 0xb9002563, 0xd1002564, 0xd2002565, + 0xcb002566, 0xcf002567, 0xd0002568, 0xca002569, 0xd800256a, 0xd700256b, 0xce00256c, 0xdf002580, + 0xdc002584, 0xdb002588, 0xdd00258c, 0xde002590, 0xb0002591, 0xb1002592, 0xb2002593, 0xfe0025a0, + }, +} + +// CodePage865 is the IBM Code Page 865 encoding. +var CodePage865 *Charmap = &codePage865 + +var codePage865 = Charmap{ + name: "IBM Code Page 865", + mib: identifier.IBM865, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {2, [3]byte{0xc3, 0x87, 0x00}}, {2, [3]byte{0xc3, 0xbc, 0x00}}, + {2, [3]byte{0xc3, 0xa9, 0x00}}, {2, [3]byte{0xc3, 0xa2, 0x00}}, + {2, [3]byte{0xc3, 0xa4, 0x00}}, {2, [3]byte{0xc3, 0xa0, 0x00}}, + {2, [3]byte{0xc3, 0xa5, 0x00}}, {2, [3]byte{0xc3, 0xa7, 0x00}}, + {2, [3]byte{0xc3, 0xaa, 0x00}}, {2, [3]byte{0xc3, 0xab, 0x00}}, + {2, [3]byte{0xc3, 0xa8, 0x00}}, {2, [3]byte{0xc3, 0xaf, 0x00}}, + {2, [3]byte{0xc3, 0xae, 0x00}}, {2, [3]byte{0xc3, 0xac, 0x00}}, + {2, [3]byte{0xc3, 0x84, 0x00}}, {2, [3]byte{0xc3, 0x85, 0x00}}, + {2, [3]byte{0xc3, 0x89, 0x00}}, {2, [3]byte{0xc3, 0xa6, 0x00}}, + {2, [3]byte{0xc3, 0x86, 0x00}}, {2, [3]byte{0xc3, 0xb4, 0x00}}, + {2, [3]byte{0xc3, 0xb6, 0x00}}, {2, [3]byte{0xc3, 0xb2, 0x00}}, + {2, [3]byte{0xc3, 0xbb, 0x00}}, {2, [3]byte{0xc3, 0xb9, 0x00}}, + {2, [3]byte{0xc3, 0xbf, 0x00}}, {2, [3]byte{0xc3, 0x96, 0x00}}, + {2, [3]byte{0xc3, 0x9c, 0x00}}, {2, [3]byte{0xc3, 0xb8, 0x00}}, + {2, [3]byte{0xc2, 0xa3, 0x00}}, {2, [3]byte{0xc3, 0x98, 0x00}}, + {3, [3]byte{0xe2, 0x82, 0xa7}}, {2, [3]byte{0xc6, 0x92, 0x00}}, + {2, [3]byte{0xc3, 0xa1, 0x00}}, {2, [3]byte{0xc3, 0xad, 0x00}}, + {2, [3]byte{0xc3, 0xb3, 0x00}}, {2, [3]byte{0xc3, 0xba, 0x00}}, + {2, [3]byte{0xc3, 0xb1, 0x00}}, {2, [3]byte{0xc3, 0x91, 0x00}}, + {2, [3]byte{0xc2, 0xaa, 0x00}}, {2, [3]byte{0xc2, 0xba, 0x00}}, + {2, [3]byte{0xc2, 0xbf, 0x00}}, {3, [3]byte{0xe2, 0x8c, 0x90}}, + {2, [3]byte{0xc2, 0xac, 0x00}}, {2, [3]byte{0xc2, 0xbd, 0x00}}, + {2, [3]byte{0xc2, 0xbc, 0x00}}, {2, [3]byte{0xc2, 0xa1, 0x00}}, + {2, [3]byte{0xc2, 0xab, 0x00}}, {2, [3]byte{0xc2, 0xa4, 0x00}}, + {3, [3]byte{0xe2, 0x96, 0x91}}, {3, [3]byte{0xe2, 0x96, 0x92}}, + {3, [3]byte{0xe2, 0x96, 0x93}}, {3, [3]byte{0xe2, 0x94, 0x82}}, + {3, [3]byte{0xe2, 0x94, 0xa4}}, {3, [3]byte{0xe2, 0x95, 0xa1}}, + {3, [3]byte{0xe2, 0x95, 0xa2}}, {3, [3]byte{0xe2, 0x95, 0x96}}, + {3, [3]byte{0xe2, 0x95, 0x95}}, {3, [3]byte{0xe2, 0x95, 0xa3}}, + {3, [3]byte{0xe2, 0x95, 0x91}}, {3, [3]byte{0xe2, 0x95, 0x97}}, + {3, [3]byte{0xe2, 0x95, 0x9d}}, {3, [3]byte{0xe2, 0x95, 0x9c}}, + {3, [3]byte{0xe2, 0x95, 0x9b}}, {3, [3]byte{0xe2, 0x94, 0x90}}, + {3, [3]byte{0xe2, 0x94, 0x94}}, {3, [3]byte{0xe2, 0x94, 0xb4}}, + {3, [3]byte{0xe2, 0x94, 0xac}}, {3, [3]byte{0xe2, 0x94, 0x9c}}, + {3, [3]byte{0xe2, 0x94, 0x80}}, {3, [3]byte{0xe2, 0x94, 0xbc}}, + {3, [3]byte{0xe2, 0x95, 0x9e}}, {3, [3]byte{0xe2, 0x95, 0x9f}}, + {3, [3]byte{0xe2, 0x95, 0x9a}}, {3, [3]byte{0xe2, 0x95, 0x94}}, + {3, [3]byte{0xe2, 0x95, 0xa9}}, {3, [3]byte{0xe2, 0x95, 0xa6}}, + {3, [3]byte{0xe2, 0x95, 0xa0}}, {3, [3]byte{0xe2, 0x95, 0x90}}, + {3, [3]byte{0xe2, 0x95, 0xac}}, {3, [3]byte{0xe2, 0x95, 0xa7}}, + {3, [3]byte{0xe2, 0x95, 0xa8}}, {3, [3]byte{0xe2, 0x95, 0xa4}}, + {3, [3]byte{0xe2, 0x95, 0xa5}}, {3, [3]byte{0xe2, 0x95, 0x99}}, + {3, [3]byte{0xe2, 0x95, 0x98}}, {3, [3]byte{0xe2, 0x95, 0x92}}, + {3, [3]byte{0xe2, 0x95, 0x93}}, {3, [3]byte{0xe2, 0x95, 0xab}}, + {3, [3]byte{0xe2, 0x95, 0xaa}}, {3, [3]byte{0xe2, 0x94, 0x98}}, + {3, [3]byte{0xe2, 0x94, 0x8c}}, {3, [3]byte{0xe2, 0x96, 0x88}}, + {3, [3]byte{0xe2, 0x96, 0x84}}, {3, [3]byte{0xe2, 0x96, 0x8c}}, + {3, [3]byte{0xe2, 0x96, 0x90}}, {3, [3]byte{0xe2, 0x96, 0x80}}, + {2, [3]byte{0xce, 0xb1, 0x00}}, {2, [3]byte{0xc3, 0x9f, 0x00}}, + {2, [3]byte{0xce, 0x93, 0x00}}, {2, [3]byte{0xcf, 0x80, 0x00}}, + {2, [3]byte{0xce, 0xa3, 0x00}}, {2, [3]byte{0xcf, 0x83, 0x00}}, + {2, [3]byte{0xc2, 0xb5, 0x00}}, {2, [3]byte{0xcf, 0x84, 0x00}}, + {2, [3]byte{0xce, 0xa6, 0x00}}, {2, [3]byte{0xce, 0x98, 0x00}}, + {2, [3]byte{0xce, 0xa9, 0x00}}, {2, [3]byte{0xce, 0xb4, 0x00}}, + {3, [3]byte{0xe2, 0x88, 0x9e}}, {2, [3]byte{0xcf, 0x86, 0x00}}, + {2, [3]byte{0xce, 0xb5, 0x00}}, {3, [3]byte{0xe2, 0x88, 0xa9}}, + {3, [3]byte{0xe2, 0x89, 0xa1}}, {2, [3]byte{0xc2, 0xb1, 0x00}}, + {3, [3]byte{0xe2, 0x89, 0xa5}}, {3, [3]byte{0xe2, 0x89, 0xa4}}, + {3, [3]byte{0xe2, 0x8c, 0xa0}}, {3, [3]byte{0xe2, 0x8c, 0xa1}}, + {2, [3]byte{0xc3, 0xb7, 0x00}}, {3, [3]byte{0xe2, 0x89, 0x88}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {3, [3]byte{0xe2, 0x88, 0x99}}, + {2, [3]byte{0xc2, 0xb7, 0x00}}, {3, [3]byte{0xe2, 0x88, 0x9a}}, + {3, [3]byte{0xe2, 0x81, 0xbf}}, {2, [3]byte{0xc2, 0xb2, 0x00}}, + {3, [3]byte{0xe2, 0x96, 0xa0}}, {2, [3]byte{0xc2, 0xa0, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xff0000a0, 0xad0000a1, 0x9c0000a3, 0xaf0000a4, 0xa60000aa, 0xae0000ab, 0xaa0000ac, 0xf80000b0, + 0xf10000b1, 0xfd0000b2, 0xe60000b5, 0xfa0000b7, 0xa70000ba, 0xac0000bc, 0xab0000bd, 0xa80000bf, + 0x8e0000c4, 0x8f0000c5, 0x920000c6, 0x800000c7, 0x900000c9, 0xa50000d1, 0x990000d6, 0x9d0000d8, + 0x9a0000dc, 0xe10000df, 0x850000e0, 0xa00000e1, 0x830000e2, 0x840000e4, 0x860000e5, 0x910000e6, + 0x870000e7, 0x8a0000e8, 0x820000e9, 0x880000ea, 0x890000eb, 0x8d0000ec, 0xa10000ed, 0x8c0000ee, + 0x8b0000ef, 0xa40000f1, 0x950000f2, 0xa20000f3, 0x930000f4, 0x940000f6, 0xf60000f7, 0x9b0000f8, + 0x970000f9, 0xa30000fa, 0x960000fb, 0x810000fc, 0x980000ff, 0x9f000192, 0xe2000393, 0xe9000398, + 0xe40003a3, 0xe80003a6, 0xea0003a9, 0xe00003b1, 0xeb0003b4, 0xee0003b5, 0xe30003c0, 0xe50003c3, + 0xe70003c4, 0xed0003c6, 0xfc00207f, 0x9e0020a7, 0xf9002219, 0xfb00221a, 0xec00221e, 0xef002229, + 0xf7002248, 0xf0002261, 0xf3002264, 0xf2002265, 0xa9002310, 0xf4002320, 0xf5002321, 0xc4002500, + 0xb3002502, 0xda00250c, 0xbf002510, 0xc0002514, 0xd9002518, 0xc300251c, 0xb4002524, 0xc200252c, + 0xc1002534, 0xc500253c, 0xcd002550, 0xba002551, 0xd5002552, 0xd6002553, 0xc9002554, 0xb8002555, + 0xb7002556, 0xbb002557, 0xd4002558, 0xd3002559, 0xc800255a, 0xbe00255b, 0xbd00255c, 0xbc00255d, + 0xc600255e, 0xc700255f, 0xcc002560, 0xb5002561, 0xb6002562, 0xb9002563, 0xd1002564, 0xd2002565, + 0xcb002566, 0xcf002567, 0xd0002568, 0xca002569, 0xd800256a, 0xd700256b, 0xce00256c, 0xdf002580, + 0xdc002584, 0xdb002588, 0xdd00258c, 0xde002590, 0xb0002591, 0xb1002592, 0xb2002593, 0xfe0025a0, + }, +} + +// CodePage866 is the IBM Code Page 866 encoding. +var CodePage866 *Charmap = &codePage866 + +var codePage866 = Charmap{ + name: "IBM Code Page 866", + mib: identifier.IBM866, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {2, [3]byte{0xd0, 0x90, 0x00}}, {2, [3]byte{0xd0, 0x91, 0x00}}, + {2, [3]byte{0xd0, 0x92, 0x00}}, {2, [3]byte{0xd0, 0x93, 0x00}}, + {2, [3]byte{0xd0, 0x94, 0x00}}, {2, [3]byte{0xd0, 0x95, 0x00}}, + {2, [3]byte{0xd0, 0x96, 0x00}}, {2, [3]byte{0xd0, 0x97, 0x00}}, + {2, [3]byte{0xd0, 0x98, 0x00}}, {2, [3]byte{0xd0, 0x99, 0x00}}, + {2, [3]byte{0xd0, 0x9a, 0x00}}, {2, [3]byte{0xd0, 0x9b, 0x00}}, + {2, [3]byte{0xd0, 0x9c, 0x00}}, {2, [3]byte{0xd0, 0x9d, 0x00}}, + {2, [3]byte{0xd0, 0x9e, 0x00}}, {2, [3]byte{0xd0, 0x9f, 0x00}}, + {2, [3]byte{0xd0, 0xa0, 0x00}}, {2, [3]byte{0xd0, 0xa1, 0x00}}, + {2, [3]byte{0xd0, 0xa2, 0x00}}, {2, [3]byte{0xd0, 0xa3, 0x00}}, + {2, [3]byte{0xd0, 0xa4, 0x00}}, {2, [3]byte{0xd0, 0xa5, 0x00}}, + {2, [3]byte{0xd0, 0xa6, 0x00}}, {2, [3]byte{0xd0, 0xa7, 0x00}}, + {2, [3]byte{0xd0, 0xa8, 0x00}}, {2, [3]byte{0xd0, 0xa9, 0x00}}, + {2, [3]byte{0xd0, 0xaa, 0x00}}, {2, [3]byte{0xd0, 0xab, 0x00}}, + {2, [3]byte{0xd0, 0xac, 0x00}}, {2, [3]byte{0xd0, 0xad, 0x00}}, + {2, [3]byte{0xd0, 0xae, 0x00}}, {2, [3]byte{0xd0, 0xaf, 0x00}}, + {2, [3]byte{0xd0, 0xb0, 0x00}}, {2, [3]byte{0xd0, 0xb1, 0x00}}, + {2, [3]byte{0xd0, 0xb2, 0x00}}, {2, [3]byte{0xd0, 0xb3, 0x00}}, + {2, [3]byte{0xd0, 0xb4, 0x00}}, {2, [3]byte{0xd0, 0xb5, 0x00}}, + {2, [3]byte{0xd0, 0xb6, 0x00}}, {2, [3]byte{0xd0, 0xb7, 0x00}}, + {2, [3]byte{0xd0, 0xb8, 0x00}}, {2, [3]byte{0xd0, 0xb9, 0x00}}, + {2, [3]byte{0xd0, 0xba, 0x00}}, {2, [3]byte{0xd0, 0xbb, 0x00}}, + {2, [3]byte{0xd0, 0xbc, 0x00}}, {2, [3]byte{0xd0, 0xbd, 0x00}}, + {2, [3]byte{0xd0, 0xbe, 0x00}}, {2, [3]byte{0xd0, 0xbf, 0x00}}, + {3, [3]byte{0xe2, 0x96, 0x91}}, {3, [3]byte{0xe2, 0x96, 0x92}}, + {3, [3]byte{0xe2, 0x96, 0x93}}, {3, [3]byte{0xe2, 0x94, 0x82}}, + {3, [3]byte{0xe2, 0x94, 0xa4}}, {3, [3]byte{0xe2, 0x95, 0xa1}}, + {3, [3]byte{0xe2, 0x95, 0xa2}}, {3, [3]byte{0xe2, 0x95, 0x96}}, + {3, [3]byte{0xe2, 0x95, 0x95}}, {3, [3]byte{0xe2, 0x95, 0xa3}}, + {3, [3]byte{0xe2, 0x95, 0x91}}, {3, [3]byte{0xe2, 0x95, 0x97}}, + {3, [3]byte{0xe2, 0x95, 0x9d}}, {3, [3]byte{0xe2, 0x95, 0x9c}}, + {3, [3]byte{0xe2, 0x95, 0x9b}}, {3, [3]byte{0xe2, 0x94, 0x90}}, + {3, [3]byte{0xe2, 0x94, 0x94}}, {3, [3]byte{0xe2, 0x94, 0xb4}}, + {3, [3]byte{0xe2, 0x94, 0xac}}, {3, [3]byte{0xe2, 0x94, 0x9c}}, + {3, [3]byte{0xe2, 0x94, 0x80}}, {3, [3]byte{0xe2, 0x94, 0xbc}}, + {3, [3]byte{0xe2, 0x95, 0x9e}}, {3, [3]byte{0xe2, 0x95, 0x9f}}, + {3, [3]byte{0xe2, 0x95, 0x9a}}, {3, [3]byte{0xe2, 0x95, 0x94}}, + {3, [3]byte{0xe2, 0x95, 0xa9}}, {3, [3]byte{0xe2, 0x95, 0xa6}}, + {3, [3]byte{0xe2, 0x95, 0xa0}}, {3, [3]byte{0xe2, 0x95, 0x90}}, + {3, [3]byte{0xe2, 0x95, 0xac}}, {3, [3]byte{0xe2, 0x95, 0xa7}}, + {3, [3]byte{0xe2, 0x95, 0xa8}}, {3, [3]byte{0xe2, 0x95, 0xa4}}, + {3, [3]byte{0xe2, 0x95, 0xa5}}, {3, [3]byte{0xe2, 0x95, 0x99}}, + {3, [3]byte{0xe2, 0x95, 0x98}}, {3, [3]byte{0xe2, 0x95, 0x92}}, + {3, [3]byte{0xe2, 0x95, 0x93}}, {3, [3]byte{0xe2, 0x95, 0xab}}, + {3, [3]byte{0xe2, 0x95, 0xaa}}, {3, [3]byte{0xe2, 0x94, 0x98}}, + {3, [3]byte{0xe2, 0x94, 0x8c}}, {3, [3]byte{0xe2, 0x96, 0x88}}, + {3, [3]byte{0xe2, 0x96, 0x84}}, {3, [3]byte{0xe2, 0x96, 0x8c}}, + {3, [3]byte{0xe2, 0x96, 0x90}}, {3, [3]byte{0xe2, 0x96, 0x80}}, + {2, [3]byte{0xd1, 0x80, 0x00}}, {2, [3]byte{0xd1, 0x81, 0x00}}, + {2, [3]byte{0xd1, 0x82, 0x00}}, {2, [3]byte{0xd1, 0x83, 0x00}}, + {2, [3]byte{0xd1, 0x84, 0x00}}, {2, [3]byte{0xd1, 0x85, 0x00}}, + {2, [3]byte{0xd1, 0x86, 0x00}}, {2, [3]byte{0xd1, 0x87, 0x00}}, + {2, [3]byte{0xd1, 0x88, 0x00}}, {2, [3]byte{0xd1, 0x89, 0x00}}, + {2, [3]byte{0xd1, 0x8a, 0x00}}, {2, [3]byte{0xd1, 0x8b, 0x00}}, + {2, [3]byte{0xd1, 0x8c, 0x00}}, {2, [3]byte{0xd1, 0x8d, 0x00}}, + {2, [3]byte{0xd1, 0x8e, 0x00}}, {2, [3]byte{0xd1, 0x8f, 0x00}}, + {2, [3]byte{0xd0, 0x81, 0x00}}, {2, [3]byte{0xd1, 0x91, 0x00}}, + {2, [3]byte{0xd0, 0x84, 0x00}}, {2, [3]byte{0xd1, 0x94, 0x00}}, + {2, [3]byte{0xd0, 0x87, 0x00}}, {2, [3]byte{0xd1, 0x97, 0x00}}, + {2, [3]byte{0xd0, 0x8e, 0x00}}, {2, [3]byte{0xd1, 0x9e, 0x00}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {3, [3]byte{0xe2, 0x88, 0x99}}, + {2, [3]byte{0xc2, 0xb7, 0x00}}, {3, [3]byte{0xe2, 0x88, 0x9a}}, + {3, [3]byte{0xe2, 0x84, 0x96}}, {2, [3]byte{0xc2, 0xa4, 0x00}}, + {3, [3]byte{0xe2, 0x96, 0xa0}}, {2, [3]byte{0xc2, 0xa0, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xff0000a0, 0xfd0000a4, 0xf80000b0, 0xfa0000b7, 0xf0000401, 0xf2000404, 0xf4000407, 0xf600040e, + 0x80000410, 0x81000411, 0x82000412, 0x83000413, 0x84000414, 0x85000415, 0x86000416, 0x87000417, + 0x88000418, 0x89000419, 0x8a00041a, 0x8b00041b, 0x8c00041c, 0x8d00041d, 0x8e00041e, 0x8f00041f, + 0x90000420, 0x91000421, 0x92000422, 0x93000423, 0x94000424, 0x95000425, 0x96000426, 0x97000427, + 0x98000428, 0x99000429, 0x9a00042a, 0x9b00042b, 0x9c00042c, 0x9d00042d, 0x9e00042e, 0x9f00042f, + 0xa0000430, 0xa1000431, 0xa2000432, 0xa3000433, 0xa4000434, 0xa5000435, 0xa6000436, 0xa7000437, + 0xa8000438, 0xa9000439, 0xaa00043a, 0xab00043b, 0xac00043c, 0xad00043d, 0xae00043e, 0xaf00043f, + 0xe0000440, 0xe1000441, 0xe2000442, 0xe3000443, 0xe4000444, 0xe5000445, 0xe6000446, 0xe7000447, + 0xe8000448, 0xe9000449, 0xea00044a, 0xeb00044b, 0xec00044c, 0xed00044d, 0xee00044e, 0xef00044f, + 0xf1000451, 0xf3000454, 0xf5000457, 0xf700045e, 0xfc002116, 0xf9002219, 0xfb00221a, 0xc4002500, + 0xb3002502, 0xda00250c, 0xbf002510, 0xc0002514, 0xd9002518, 0xc300251c, 0xb4002524, 0xc200252c, + 0xc1002534, 0xc500253c, 0xcd002550, 0xba002551, 0xd5002552, 0xd6002553, 0xc9002554, 0xb8002555, + 0xb7002556, 0xbb002557, 0xd4002558, 0xd3002559, 0xc800255a, 0xbe00255b, 0xbd00255c, 0xbc00255d, + 0xc600255e, 0xc700255f, 0xcc002560, 0xb5002561, 0xb6002562, 0xb9002563, 0xd1002564, 0xd2002565, + 0xcb002566, 0xcf002567, 0xd0002568, 0xca002569, 0xd800256a, 0xd700256b, 0xce00256c, 0xdf002580, + 0xdc002584, 0xdb002588, 0xdd00258c, 0xde002590, 0xb0002591, 0xb1002592, 0xb2002593, 0xfe0025a0, + }, +} + +// CodePage1047 is the IBM Code Page 1047 encoding. +var CodePage1047 *Charmap = &codePage1047 + +var codePage1047 = Charmap{ + name: "IBM Code Page 1047", + mib: identifier.IBM1047, + asciiSuperset: false, + low: 0x00, + replacement: 0x3f, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x9c, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x86, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x97, 0x00}}, {2, [3]byte{0xc2, 0x8d, 0x00}}, + {2, [3]byte{0xc2, 0x8e, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x9d, 0x00}}, {2, [3]byte{0xc2, 0x85, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {2, [3]byte{0xc2, 0x87, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x92, 0x00}}, {2, [3]byte{0xc2, 0x8f, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x80, 0x00}}, {2, [3]byte{0xc2, 0x81, 0x00}}, + {2, [3]byte{0xc2, 0x82, 0x00}}, {2, [3]byte{0xc2, 0x83, 0x00}}, + {2, [3]byte{0xc2, 0x84, 0x00}}, {1, [3]byte{0x0a, 0x00, 0x00}}, + {1, [3]byte{0x17, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x88, 0x00}}, {2, [3]byte{0xc2, 0x89, 0x00}}, + {2, [3]byte{0xc2, 0x8a, 0x00}}, {2, [3]byte{0xc2, 0x8b, 0x00}}, + {2, [3]byte{0xc2, 0x8c, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x90, 0x00}}, {2, [3]byte{0xc2, 0x91, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {2, [3]byte{0xc2, 0x93, 0x00}}, + {2, [3]byte{0xc2, 0x94, 0x00}}, {2, [3]byte{0xc2, 0x95, 0x00}}, + {2, [3]byte{0xc2, 0x96, 0x00}}, {1, [3]byte{0x04, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x98, 0x00}}, {2, [3]byte{0xc2, 0x99, 0x00}}, + {2, [3]byte{0xc2, 0x9a, 0x00}}, {2, [3]byte{0xc2, 0x9b, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x9e, 0x00}}, {1, [3]byte{0x1a, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {2, [3]byte{0xc2, 0xa0, 0x00}}, + {2, [3]byte{0xc3, 0xa2, 0x00}}, {2, [3]byte{0xc3, 0xa4, 0x00}}, + {2, [3]byte{0xc3, 0xa0, 0x00}}, {2, [3]byte{0xc3, 0xa1, 0x00}}, + {2, [3]byte{0xc3, 0xa3, 0x00}}, {2, [3]byte{0xc3, 0xa5, 0x00}}, + {2, [3]byte{0xc3, 0xa7, 0x00}}, {2, [3]byte{0xc3, 0xb1, 0x00}}, + {2, [3]byte{0xc2, 0xa2, 0x00}}, {1, [3]byte{0x2e, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x28, 0x00, 0x00}}, + {1, [3]byte{0x2b, 0x00, 0x00}}, {1, [3]byte{0x7c, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {2, [3]byte{0xc3, 0xa9, 0x00}}, + {2, [3]byte{0xc3, 0xaa, 0x00}}, {2, [3]byte{0xc3, 0xab, 0x00}}, + {2, [3]byte{0xc3, 0xa8, 0x00}}, {2, [3]byte{0xc3, 0xad, 0x00}}, + {2, [3]byte{0xc3, 0xae, 0x00}}, {2, [3]byte{0xc3, 0xaf, 0x00}}, + {2, [3]byte{0xc3, 0xac, 0x00}}, {2, [3]byte{0xc3, 0x9f, 0x00}}, + {1, [3]byte{0x21, 0x00, 0x00}}, {1, [3]byte{0x24, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x3b, 0x00, 0x00}}, {1, [3]byte{0x5e, 0x00, 0x00}}, + {1, [3]byte{0x2d, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {2, [3]byte{0xc3, 0x82, 0x00}}, {2, [3]byte{0xc3, 0x84, 0x00}}, + {2, [3]byte{0xc3, 0x80, 0x00}}, {2, [3]byte{0xc3, 0x81, 0x00}}, + {2, [3]byte{0xc3, 0x83, 0x00}}, {2, [3]byte{0xc3, 0x85, 0x00}}, + {2, [3]byte{0xc3, 0x87, 0x00}}, {2, [3]byte{0xc3, 0x91, 0x00}}, + {2, [3]byte{0xc2, 0xa6, 0x00}}, {1, [3]byte{0x2c, 0x00, 0x00}}, + {1, [3]byte{0x25, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {2, [3]byte{0xc3, 0xb8, 0x00}}, {2, [3]byte{0xc3, 0x89, 0x00}}, + {2, [3]byte{0xc3, 0x8a, 0x00}}, {2, [3]byte{0xc3, 0x8b, 0x00}}, + {2, [3]byte{0xc3, 0x88, 0x00}}, {2, [3]byte{0xc3, 0x8d, 0x00}}, + {2, [3]byte{0xc3, 0x8e, 0x00}}, {2, [3]byte{0xc3, 0x8f, 0x00}}, + {2, [3]byte{0xc3, 0x8c, 0x00}}, {1, [3]byte{0x60, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x3d, 0x00, 0x00}}, {1, [3]byte{0x22, 0x00, 0x00}}, + {2, [3]byte{0xc3, 0x98, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0xab, 0x00}}, {2, [3]byte{0xc2, 0xbb, 0x00}}, + {2, [3]byte{0xc3, 0xb0, 0x00}}, {2, [3]byte{0xc3, 0xbd, 0x00}}, + {2, [3]byte{0xc3, 0xbe, 0x00}}, {2, [3]byte{0xc2, 0xb1, 0x00}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {1, [3]byte{0x6a, 0x00, 0x00}}, + {1, [3]byte{0x6b, 0x00, 0x00}}, {1, [3]byte{0x6c, 0x00, 0x00}}, + {1, [3]byte{0x6d, 0x00, 0x00}}, {1, [3]byte{0x6e, 0x00, 0x00}}, + {1, [3]byte{0x6f, 0x00, 0x00}}, {1, [3]byte{0x70, 0x00, 0x00}}, + {1, [3]byte{0x71, 0x00, 0x00}}, {1, [3]byte{0x72, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0xaa, 0x00}}, {2, [3]byte{0xc2, 0xba, 0x00}}, + {2, [3]byte{0xc3, 0xa6, 0x00}}, {2, [3]byte{0xc2, 0xb8, 0x00}}, + {2, [3]byte{0xc3, 0x86, 0x00}}, {2, [3]byte{0xc2, 0xa4, 0x00}}, + {2, [3]byte{0xc2, 0xb5, 0x00}}, {1, [3]byte{0x7e, 0x00, 0x00}}, + {1, [3]byte{0x73, 0x00, 0x00}}, {1, [3]byte{0x74, 0x00, 0x00}}, + {1, [3]byte{0x75, 0x00, 0x00}}, {1, [3]byte{0x76, 0x00, 0x00}}, + {1, [3]byte{0x77, 0x00, 0x00}}, {1, [3]byte{0x78, 0x00, 0x00}}, + {1, [3]byte{0x79, 0x00, 0x00}}, {1, [3]byte{0x7a, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0xa1, 0x00}}, {2, [3]byte{0xc2, 0xbf, 0x00}}, + {2, [3]byte{0xc3, 0x90, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {2, [3]byte{0xc3, 0x9e, 0x00}}, {2, [3]byte{0xc2, 0xae, 0x00}}, + {2, [3]byte{0xc2, 0xac, 0x00}}, {2, [3]byte{0xc2, 0xa3, 0x00}}, + {2, [3]byte{0xc2, 0xa5, 0x00}}, {2, [3]byte{0xc2, 0xb7, 0x00}}, + {2, [3]byte{0xc2, 0xa9, 0x00}}, {2, [3]byte{0xc2, 0xa7, 0x00}}, + {2, [3]byte{0xc2, 0xb6, 0x00}}, {2, [3]byte{0xc2, 0xbc, 0x00}}, + {2, [3]byte{0xc2, 0xbd, 0x00}}, {2, [3]byte{0xc2, 0xbe, 0x00}}, + {2, [3]byte{0xc3, 0x9d, 0x00}}, {2, [3]byte{0xc2, 0xa8, 0x00}}, + {2, [3]byte{0xc2, 0xaf, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0xb4, 0x00}}, {2, [3]byte{0xc3, 0x97, 0x00}}, + {1, [3]byte{0x7b, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0xad, 0x00}}, {2, [3]byte{0xc3, 0xb4, 0x00}}, + {2, [3]byte{0xc3, 0xb6, 0x00}}, {2, [3]byte{0xc3, 0xb2, 0x00}}, + {2, [3]byte{0xc3, 0xb3, 0x00}}, {2, [3]byte{0xc3, 0xb5, 0x00}}, + {1, [3]byte{0x7d, 0x00, 0x00}}, {1, [3]byte{0x4a, 0x00, 0x00}}, + {1, [3]byte{0x4b, 0x00, 0x00}}, {1, [3]byte{0x4c, 0x00, 0x00}}, + {1, [3]byte{0x4d, 0x00, 0x00}}, {1, [3]byte{0x4e, 0x00, 0x00}}, + {1, [3]byte{0x4f, 0x00, 0x00}}, {1, [3]byte{0x50, 0x00, 0x00}}, + {1, [3]byte{0x51, 0x00, 0x00}}, {1, [3]byte{0x52, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0xb9, 0x00}}, {2, [3]byte{0xc3, 0xbb, 0x00}}, + {2, [3]byte{0xc3, 0xbc, 0x00}}, {2, [3]byte{0xc3, 0xb9, 0x00}}, + {2, [3]byte{0xc3, 0xba, 0x00}}, {2, [3]byte{0xc3, 0xbf, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {2, [3]byte{0xc3, 0xb7, 0x00}}, + {1, [3]byte{0x53, 0x00, 0x00}}, {1, [3]byte{0x54, 0x00, 0x00}}, + {1, [3]byte{0x55, 0x00, 0x00}}, {1, [3]byte{0x56, 0x00, 0x00}}, + {1, [3]byte{0x57, 0x00, 0x00}}, {1, [3]byte{0x58, 0x00, 0x00}}, + {1, [3]byte{0x59, 0x00, 0x00}}, {1, [3]byte{0x5a, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0xb2, 0x00}}, {2, [3]byte{0xc3, 0x94, 0x00}}, + {2, [3]byte{0xc3, 0x96, 0x00}}, {2, [3]byte{0xc3, 0x92, 0x00}}, + {2, [3]byte{0xc3, 0x93, 0x00}}, {2, [3]byte{0xc3, 0x95, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0xb3, 0x00}}, {2, [3]byte{0xc3, 0x9b, 0x00}}, + {2, [3]byte{0xc3, 0x9c, 0x00}}, {2, [3]byte{0xc3, 0x99, 0x00}}, + {2, [3]byte{0xc3, 0x9a, 0x00}}, {2, [3]byte{0xc2, 0x9f, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x37000004, 0x2d000005, 0x2e000006, 0x2f000007, + 0x16000008, 0x05000009, 0x2500000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x3c000014, 0x3d000015, 0x32000016, 0x26000017, + 0x18000018, 0x19000019, 0x3f00001a, 0x2700001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x40000020, 0x5a000021, 0x7f000022, 0x7b000023, 0x5b000024, 0x6c000025, 0x50000026, 0x7d000027, + 0x4d000028, 0x5d000029, 0x5c00002a, 0x4e00002b, 0x6b00002c, 0x6000002d, 0x4b00002e, 0x6100002f, + 0xf0000030, 0xf1000031, 0xf2000032, 0xf3000033, 0xf4000034, 0xf5000035, 0xf6000036, 0xf7000037, + 0xf8000038, 0xf9000039, 0x7a00003a, 0x5e00003b, 0x4c00003c, 0x7e00003d, 0x6e00003e, 0x6f00003f, + 0x7c000040, 0xc1000041, 0xc2000042, 0xc3000043, 0xc4000044, 0xc5000045, 0xc6000046, 0xc7000047, + 0xc8000048, 0xc9000049, 0xd100004a, 0xd200004b, 0xd300004c, 0xd400004d, 0xd500004e, 0xd600004f, + 0xd7000050, 0xd8000051, 0xd9000052, 0xe2000053, 0xe3000054, 0xe4000055, 0xe5000056, 0xe6000057, + 0xe7000058, 0xe8000059, 0xe900005a, 0xad00005b, 0xe000005c, 0xbd00005d, 0x5f00005e, 0x6d00005f, + 0x79000060, 0x81000061, 0x82000062, 0x83000063, 0x84000064, 0x85000065, 0x86000066, 0x87000067, + 0x88000068, 0x89000069, 0x9100006a, 0x9200006b, 0x9300006c, 0x9400006d, 0x9500006e, 0x9600006f, + 0x97000070, 0x98000071, 0x99000072, 0xa2000073, 0xa3000074, 0xa4000075, 0xa5000076, 0xa6000077, + 0xa7000078, 0xa8000079, 0xa900007a, 0xc000007b, 0x4f00007c, 0xd000007d, 0xa100007e, 0x0700007f, + 0x20000080, 0x21000081, 0x22000082, 0x23000083, 0x24000084, 0x15000085, 0x06000086, 0x17000087, + 0x28000088, 0x29000089, 0x2a00008a, 0x2b00008b, 0x2c00008c, 0x0900008d, 0x0a00008e, 0x1b00008f, + 0x30000090, 0x31000091, 0x1a000092, 0x33000093, 0x34000094, 0x35000095, 0x36000096, 0x08000097, + 0x38000098, 0x39000099, 0x3a00009a, 0x3b00009b, 0x0400009c, 0x1400009d, 0x3e00009e, 0xff00009f, + 0x410000a0, 0xaa0000a1, 0x4a0000a2, 0xb10000a3, 0x9f0000a4, 0xb20000a5, 0x6a0000a6, 0xb50000a7, + 0xbb0000a8, 0xb40000a9, 0x9a0000aa, 0x8a0000ab, 0xb00000ac, 0xca0000ad, 0xaf0000ae, 0xbc0000af, + 0x900000b0, 0x8f0000b1, 0xea0000b2, 0xfa0000b3, 0xbe0000b4, 0xa00000b5, 0xb60000b6, 0xb30000b7, + 0x9d0000b8, 0xda0000b9, 0x9b0000ba, 0x8b0000bb, 0xb70000bc, 0xb80000bd, 0xb90000be, 0xab0000bf, + 0x640000c0, 0x650000c1, 0x620000c2, 0x660000c3, 0x630000c4, 0x670000c5, 0x9e0000c6, 0x680000c7, + 0x740000c8, 0x710000c9, 0x720000ca, 0x730000cb, 0x780000cc, 0x750000cd, 0x760000ce, 0x770000cf, + 0xac0000d0, 0x690000d1, 0xed0000d2, 0xee0000d3, 0xeb0000d4, 0xef0000d5, 0xec0000d6, 0xbf0000d7, + 0x800000d8, 0xfd0000d9, 0xfe0000da, 0xfb0000db, 0xfc0000dc, 0xba0000dd, 0xae0000de, 0x590000df, + 0x440000e0, 0x450000e1, 0x420000e2, 0x460000e3, 0x430000e4, 0x470000e5, 0x9c0000e6, 0x480000e7, + 0x540000e8, 0x510000e9, 0x520000ea, 0x530000eb, 0x580000ec, 0x550000ed, 0x560000ee, 0x570000ef, + 0x8c0000f0, 0x490000f1, 0xcd0000f2, 0xce0000f3, 0xcb0000f4, 0xcf0000f5, 0xcc0000f6, 0xe10000f7, + 0x700000f8, 0xdd0000f9, 0xde0000fa, 0xdb0000fb, 0xdc0000fc, 0x8d0000fd, 0x8e0000fe, 0xdf0000ff, + }, +} + +// CodePage1140 is the IBM Code Page 1140 encoding. +var CodePage1140 *Charmap = &codePage1140 + +var codePage1140 = Charmap{ + name: "IBM Code Page 1140", + mib: identifier.IBM01140, + asciiSuperset: false, + low: 0x00, + replacement: 0x3f, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x9c, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x86, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x97, 0x00}}, {2, [3]byte{0xc2, 0x8d, 0x00}}, + {2, [3]byte{0xc2, 0x8e, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x9d, 0x00}}, {2, [3]byte{0xc2, 0x85, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {2, [3]byte{0xc2, 0x87, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x92, 0x00}}, {2, [3]byte{0xc2, 0x8f, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x80, 0x00}}, {2, [3]byte{0xc2, 0x81, 0x00}}, + {2, [3]byte{0xc2, 0x82, 0x00}}, {2, [3]byte{0xc2, 0x83, 0x00}}, + {2, [3]byte{0xc2, 0x84, 0x00}}, {1, [3]byte{0x0a, 0x00, 0x00}}, + {1, [3]byte{0x17, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x88, 0x00}}, {2, [3]byte{0xc2, 0x89, 0x00}}, + {2, [3]byte{0xc2, 0x8a, 0x00}}, {2, [3]byte{0xc2, 0x8b, 0x00}}, + {2, [3]byte{0xc2, 0x8c, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x90, 0x00}}, {2, [3]byte{0xc2, 0x91, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {2, [3]byte{0xc2, 0x93, 0x00}}, + {2, [3]byte{0xc2, 0x94, 0x00}}, {2, [3]byte{0xc2, 0x95, 0x00}}, + {2, [3]byte{0xc2, 0x96, 0x00}}, {1, [3]byte{0x04, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x98, 0x00}}, {2, [3]byte{0xc2, 0x99, 0x00}}, + {2, [3]byte{0xc2, 0x9a, 0x00}}, {2, [3]byte{0xc2, 0x9b, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x9e, 0x00}}, {1, [3]byte{0x1a, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {2, [3]byte{0xc2, 0xa0, 0x00}}, + {2, [3]byte{0xc3, 0xa2, 0x00}}, {2, [3]byte{0xc3, 0xa4, 0x00}}, + {2, [3]byte{0xc3, 0xa0, 0x00}}, {2, [3]byte{0xc3, 0xa1, 0x00}}, + {2, [3]byte{0xc3, 0xa3, 0x00}}, {2, [3]byte{0xc3, 0xa5, 0x00}}, + {2, [3]byte{0xc3, 0xa7, 0x00}}, {2, [3]byte{0xc3, 0xb1, 0x00}}, + {2, [3]byte{0xc2, 0xa2, 0x00}}, {1, [3]byte{0x2e, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x28, 0x00, 0x00}}, + {1, [3]byte{0x2b, 0x00, 0x00}}, {1, [3]byte{0x7c, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {2, [3]byte{0xc3, 0xa9, 0x00}}, + {2, [3]byte{0xc3, 0xaa, 0x00}}, {2, [3]byte{0xc3, 0xab, 0x00}}, + {2, [3]byte{0xc3, 0xa8, 0x00}}, {2, [3]byte{0xc3, 0xad, 0x00}}, + {2, [3]byte{0xc3, 0xae, 0x00}}, {2, [3]byte{0xc3, 0xaf, 0x00}}, + {2, [3]byte{0xc3, 0xac, 0x00}}, {2, [3]byte{0xc3, 0x9f, 0x00}}, + {1, [3]byte{0x21, 0x00, 0x00}}, {1, [3]byte{0x24, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x3b, 0x00, 0x00}}, {2, [3]byte{0xc2, 0xac, 0x00}}, + {1, [3]byte{0x2d, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {2, [3]byte{0xc3, 0x82, 0x00}}, {2, [3]byte{0xc3, 0x84, 0x00}}, + {2, [3]byte{0xc3, 0x80, 0x00}}, {2, [3]byte{0xc3, 0x81, 0x00}}, + {2, [3]byte{0xc3, 0x83, 0x00}}, {2, [3]byte{0xc3, 0x85, 0x00}}, + {2, [3]byte{0xc3, 0x87, 0x00}}, {2, [3]byte{0xc3, 0x91, 0x00}}, + {2, [3]byte{0xc2, 0xa6, 0x00}}, {1, [3]byte{0x2c, 0x00, 0x00}}, + {1, [3]byte{0x25, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {2, [3]byte{0xc3, 0xb8, 0x00}}, {2, [3]byte{0xc3, 0x89, 0x00}}, + {2, [3]byte{0xc3, 0x8a, 0x00}}, {2, [3]byte{0xc3, 0x8b, 0x00}}, + {2, [3]byte{0xc3, 0x88, 0x00}}, {2, [3]byte{0xc3, 0x8d, 0x00}}, + {2, [3]byte{0xc3, 0x8e, 0x00}}, {2, [3]byte{0xc3, 0x8f, 0x00}}, + {2, [3]byte{0xc3, 0x8c, 0x00}}, {1, [3]byte{0x60, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x3d, 0x00, 0x00}}, {1, [3]byte{0x22, 0x00, 0x00}}, + {2, [3]byte{0xc3, 0x98, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0xab, 0x00}}, {2, [3]byte{0xc2, 0xbb, 0x00}}, + {2, [3]byte{0xc3, 0xb0, 0x00}}, {2, [3]byte{0xc3, 0xbd, 0x00}}, + {2, [3]byte{0xc3, 0xbe, 0x00}}, {2, [3]byte{0xc2, 0xb1, 0x00}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {1, [3]byte{0x6a, 0x00, 0x00}}, + {1, [3]byte{0x6b, 0x00, 0x00}}, {1, [3]byte{0x6c, 0x00, 0x00}}, + {1, [3]byte{0x6d, 0x00, 0x00}}, {1, [3]byte{0x6e, 0x00, 0x00}}, + {1, [3]byte{0x6f, 0x00, 0x00}}, {1, [3]byte{0x70, 0x00, 0x00}}, + {1, [3]byte{0x71, 0x00, 0x00}}, {1, [3]byte{0x72, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0xaa, 0x00}}, {2, [3]byte{0xc2, 0xba, 0x00}}, + {2, [3]byte{0xc3, 0xa6, 0x00}}, {2, [3]byte{0xc2, 0xb8, 0x00}}, + {2, [3]byte{0xc3, 0x86, 0x00}}, {3, [3]byte{0xe2, 0x82, 0xac}}, + {2, [3]byte{0xc2, 0xb5, 0x00}}, {1, [3]byte{0x7e, 0x00, 0x00}}, + {1, [3]byte{0x73, 0x00, 0x00}}, {1, [3]byte{0x74, 0x00, 0x00}}, + {1, [3]byte{0x75, 0x00, 0x00}}, {1, [3]byte{0x76, 0x00, 0x00}}, + {1, [3]byte{0x77, 0x00, 0x00}}, {1, [3]byte{0x78, 0x00, 0x00}}, + {1, [3]byte{0x79, 0x00, 0x00}}, {1, [3]byte{0x7a, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0xa1, 0x00}}, {2, [3]byte{0xc2, 0xbf, 0x00}}, + {2, [3]byte{0xc3, 0x90, 0x00}}, {2, [3]byte{0xc3, 0x9d, 0x00}}, + {2, [3]byte{0xc3, 0x9e, 0x00}}, {2, [3]byte{0xc2, 0xae, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {2, [3]byte{0xc2, 0xa3, 0x00}}, + {2, [3]byte{0xc2, 0xa5, 0x00}}, {2, [3]byte{0xc2, 0xb7, 0x00}}, + {2, [3]byte{0xc2, 0xa9, 0x00}}, {2, [3]byte{0xc2, 0xa7, 0x00}}, + {2, [3]byte{0xc2, 0xb6, 0x00}}, {2, [3]byte{0xc2, 0xbc, 0x00}}, + {2, [3]byte{0xc2, 0xbd, 0x00}}, {2, [3]byte{0xc2, 0xbe, 0x00}}, + {1, [3]byte{0x5b, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0xaf, 0x00}}, {2, [3]byte{0xc2, 0xa8, 0x00}}, + {2, [3]byte{0xc2, 0xb4, 0x00}}, {2, [3]byte{0xc3, 0x97, 0x00}}, + {1, [3]byte{0x7b, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0xad, 0x00}}, {2, [3]byte{0xc3, 0xb4, 0x00}}, + {2, [3]byte{0xc3, 0xb6, 0x00}}, {2, [3]byte{0xc3, 0xb2, 0x00}}, + {2, [3]byte{0xc3, 0xb3, 0x00}}, {2, [3]byte{0xc3, 0xb5, 0x00}}, + {1, [3]byte{0x7d, 0x00, 0x00}}, {1, [3]byte{0x4a, 0x00, 0x00}}, + {1, [3]byte{0x4b, 0x00, 0x00}}, {1, [3]byte{0x4c, 0x00, 0x00}}, + {1, [3]byte{0x4d, 0x00, 0x00}}, {1, [3]byte{0x4e, 0x00, 0x00}}, + {1, [3]byte{0x4f, 0x00, 0x00}}, {1, [3]byte{0x50, 0x00, 0x00}}, + {1, [3]byte{0x51, 0x00, 0x00}}, {1, [3]byte{0x52, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0xb9, 0x00}}, {2, [3]byte{0xc3, 0xbb, 0x00}}, + {2, [3]byte{0xc3, 0xbc, 0x00}}, {2, [3]byte{0xc3, 0xb9, 0x00}}, + {2, [3]byte{0xc3, 0xba, 0x00}}, {2, [3]byte{0xc3, 0xbf, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {2, [3]byte{0xc3, 0xb7, 0x00}}, + {1, [3]byte{0x53, 0x00, 0x00}}, {1, [3]byte{0x54, 0x00, 0x00}}, + {1, [3]byte{0x55, 0x00, 0x00}}, {1, [3]byte{0x56, 0x00, 0x00}}, + {1, [3]byte{0x57, 0x00, 0x00}}, {1, [3]byte{0x58, 0x00, 0x00}}, + {1, [3]byte{0x59, 0x00, 0x00}}, {1, [3]byte{0x5a, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0xb2, 0x00}}, {2, [3]byte{0xc3, 0x94, 0x00}}, + {2, [3]byte{0xc3, 0x96, 0x00}}, {2, [3]byte{0xc3, 0x92, 0x00}}, + {2, [3]byte{0xc3, 0x93, 0x00}}, {2, [3]byte{0xc3, 0x95, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0xb3, 0x00}}, {2, [3]byte{0xc3, 0x9b, 0x00}}, + {2, [3]byte{0xc3, 0x9c, 0x00}}, {2, [3]byte{0xc3, 0x99, 0x00}}, + {2, [3]byte{0xc3, 0x9a, 0x00}}, {2, [3]byte{0xc2, 0x9f, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x37000004, 0x2d000005, 0x2e000006, 0x2f000007, + 0x16000008, 0x05000009, 0x2500000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x3c000014, 0x3d000015, 0x32000016, 0x26000017, + 0x18000018, 0x19000019, 0x3f00001a, 0x2700001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x40000020, 0x5a000021, 0x7f000022, 0x7b000023, 0x5b000024, 0x6c000025, 0x50000026, 0x7d000027, + 0x4d000028, 0x5d000029, 0x5c00002a, 0x4e00002b, 0x6b00002c, 0x6000002d, 0x4b00002e, 0x6100002f, + 0xf0000030, 0xf1000031, 0xf2000032, 0xf3000033, 0xf4000034, 0xf5000035, 0xf6000036, 0xf7000037, + 0xf8000038, 0xf9000039, 0x7a00003a, 0x5e00003b, 0x4c00003c, 0x7e00003d, 0x6e00003e, 0x6f00003f, + 0x7c000040, 0xc1000041, 0xc2000042, 0xc3000043, 0xc4000044, 0xc5000045, 0xc6000046, 0xc7000047, + 0xc8000048, 0xc9000049, 0xd100004a, 0xd200004b, 0xd300004c, 0xd400004d, 0xd500004e, 0xd600004f, + 0xd7000050, 0xd8000051, 0xd9000052, 0xe2000053, 0xe3000054, 0xe4000055, 0xe5000056, 0xe6000057, + 0xe7000058, 0xe8000059, 0xe900005a, 0xba00005b, 0xe000005c, 0xbb00005d, 0xb000005e, 0x6d00005f, + 0x79000060, 0x81000061, 0x82000062, 0x83000063, 0x84000064, 0x85000065, 0x86000066, 0x87000067, + 0x88000068, 0x89000069, 0x9100006a, 0x9200006b, 0x9300006c, 0x9400006d, 0x9500006e, 0x9600006f, + 0x97000070, 0x98000071, 0x99000072, 0xa2000073, 0xa3000074, 0xa4000075, 0xa5000076, 0xa6000077, + 0xa7000078, 0xa8000079, 0xa900007a, 0xc000007b, 0x4f00007c, 0xd000007d, 0xa100007e, 0x0700007f, + 0x20000080, 0x21000081, 0x22000082, 0x23000083, 0x24000084, 0x15000085, 0x06000086, 0x17000087, + 0x28000088, 0x29000089, 0x2a00008a, 0x2b00008b, 0x2c00008c, 0x0900008d, 0x0a00008e, 0x1b00008f, + 0x30000090, 0x31000091, 0x1a000092, 0x33000093, 0x34000094, 0x35000095, 0x36000096, 0x08000097, + 0x38000098, 0x39000099, 0x3a00009a, 0x3b00009b, 0x0400009c, 0x1400009d, 0x3e00009e, 0xff00009f, + 0x410000a0, 0xaa0000a1, 0x4a0000a2, 0xb10000a3, 0xb20000a5, 0x6a0000a6, 0xb50000a7, 0xbd0000a8, + 0xb40000a9, 0x9a0000aa, 0x8a0000ab, 0x5f0000ac, 0xca0000ad, 0xaf0000ae, 0xbc0000af, 0x900000b0, + 0x8f0000b1, 0xea0000b2, 0xfa0000b3, 0xbe0000b4, 0xa00000b5, 0xb60000b6, 0xb30000b7, 0x9d0000b8, + 0xda0000b9, 0x9b0000ba, 0x8b0000bb, 0xb70000bc, 0xb80000bd, 0xb90000be, 0xab0000bf, 0x640000c0, + 0x650000c1, 0x620000c2, 0x660000c3, 0x630000c4, 0x670000c5, 0x9e0000c6, 0x680000c7, 0x740000c8, + 0x710000c9, 0x720000ca, 0x730000cb, 0x780000cc, 0x750000cd, 0x760000ce, 0x770000cf, 0xac0000d0, + 0x690000d1, 0xed0000d2, 0xee0000d3, 0xeb0000d4, 0xef0000d5, 0xec0000d6, 0xbf0000d7, 0x800000d8, + 0xfd0000d9, 0xfe0000da, 0xfb0000db, 0xfc0000dc, 0xad0000dd, 0xae0000de, 0x590000df, 0x440000e0, + 0x450000e1, 0x420000e2, 0x460000e3, 0x430000e4, 0x470000e5, 0x9c0000e6, 0x480000e7, 0x540000e8, + 0x510000e9, 0x520000ea, 0x530000eb, 0x580000ec, 0x550000ed, 0x560000ee, 0x570000ef, 0x8c0000f0, + 0x490000f1, 0xcd0000f2, 0xce0000f3, 0xcb0000f4, 0xcf0000f5, 0xcc0000f6, 0xe10000f7, 0x700000f8, + 0xdd0000f9, 0xde0000fa, 0xdb0000fb, 0xdc0000fc, 0x8d0000fd, 0x8e0000fe, 0xdf0000ff, 0x9f0020ac, + }, +} + +// ISO8859_1 is the ISO 8859-1 encoding. +var ISO8859_1 *Charmap = &iso8859_1 + +var iso8859_1 = Charmap{ + name: "ISO 8859-1", + mib: identifier.ISOLatin1, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x80, 0x00}}, {2, [3]byte{0xc2, 0x81, 0x00}}, + {2, [3]byte{0xc2, 0x82, 0x00}}, {2, [3]byte{0xc2, 0x83, 0x00}}, + {2, [3]byte{0xc2, 0x84, 0x00}}, {2, [3]byte{0xc2, 0x85, 0x00}}, + {2, [3]byte{0xc2, 0x86, 0x00}}, {2, [3]byte{0xc2, 0x87, 0x00}}, + {2, [3]byte{0xc2, 0x88, 0x00}}, {2, [3]byte{0xc2, 0x89, 0x00}}, + {2, [3]byte{0xc2, 0x8a, 0x00}}, {2, [3]byte{0xc2, 0x8b, 0x00}}, + {2, [3]byte{0xc2, 0x8c, 0x00}}, {2, [3]byte{0xc2, 0x8d, 0x00}}, + {2, [3]byte{0xc2, 0x8e, 0x00}}, {2, [3]byte{0xc2, 0x8f, 0x00}}, + {2, [3]byte{0xc2, 0x90, 0x00}}, {2, [3]byte{0xc2, 0x91, 0x00}}, + {2, [3]byte{0xc2, 0x92, 0x00}}, {2, [3]byte{0xc2, 0x93, 0x00}}, + {2, [3]byte{0xc2, 0x94, 0x00}}, {2, [3]byte{0xc2, 0x95, 0x00}}, + {2, [3]byte{0xc2, 0x96, 0x00}}, {2, [3]byte{0xc2, 0x97, 0x00}}, + {2, [3]byte{0xc2, 0x98, 0x00}}, {2, [3]byte{0xc2, 0x99, 0x00}}, + {2, [3]byte{0xc2, 0x9a, 0x00}}, {2, [3]byte{0xc2, 0x9b, 0x00}}, + {2, [3]byte{0xc2, 0x9c, 0x00}}, {2, [3]byte{0xc2, 0x9d, 0x00}}, + {2, [3]byte{0xc2, 0x9e, 0x00}}, {2, [3]byte{0xc2, 0x9f, 0x00}}, + {2, [3]byte{0xc2, 0xa0, 0x00}}, {2, [3]byte{0xc2, 0xa1, 0x00}}, + {2, [3]byte{0xc2, 0xa2, 0x00}}, {2, [3]byte{0xc2, 0xa3, 0x00}}, + {2, [3]byte{0xc2, 0xa4, 0x00}}, {2, [3]byte{0xc2, 0xa5, 0x00}}, + {2, [3]byte{0xc2, 0xa6, 0x00}}, {2, [3]byte{0xc2, 0xa7, 0x00}}, + {2, [3]byte{0xc2, 0xa8, 0x00}}, {2, [3]byte{0xc2, 0xa9, 0x00}}, + {2, [3]byte{0xc2, 0xaa, 0x00}}, {2, [3]byte{0xc2, 0xab, 0x00}}, + {2, [3]byte{0xc2, 0xac, 0x00}}, {2, [3]byte{0xc2, 0xad, 0x00}}, + {2, [3]byte{0xc2, 0xae, 0x00}}, {2, [3]byte{0xc2, 0xaf, 0x00}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {2, [3]byte{0xc2, 0xb1, 0x00}}, + {2, [3]byte{0xc2, 0xb2, 0x00}}, {2, [3]byte{0xc2, 0xb3, 0x00}}, + {2, [3]byte{0xc2, 0xb4, 0x00}}, {2, [3]byte{0xc2, 0xb5, 0x00}}, + {2, [3]byte{0xc2, 0xb6, 0x00}}, {2, [3]byte{0xc2, 0xb7, 0x00}}, + {2, [3]byte{0xc2, 0xb8, 0x00}}, {2, [3]byte{0xc2, 0xb9, 0x00}}, + {2, [3]byte{0xc2, 0xba, 0x00}}, {2, [3]byte{0xc2, 0xbb, 0x00}}, + {2, [3]byte{0xc2, 0xbc, 0x00}}, {2, [3]byte{0xc2, 0xbd, 0x00}}, + {2, [3]byte{0xc2, 0xbe, 0x00}}, {2, [3]byte{0xc2, 0xbf, 0x00}}, + {2, [3]byte{0xc3, 0x80, 0x00}}, {2, [3]byte{0xc3, 0x81, 0x00}}, + {2, [3]byte{0xc3, 0x82, 0x00}}, {2, [3]byte{0xc3, 0x83, 0x00}}, + {2, [3]byte{0xc3, 0x84, 0x00}}, {2, [3]byte{0xc3, 0x85, 0x00}}, + {2, [3]byte{0xc3, 0x86, 0x00}}, {2, [3]byte{0xc3, 0x87, 0x00}}, + {2, [3]byte{0xc3, 0x88, 0x00}}, {2, [3]byte{0xc3, 0x89, 0x00}}, + {2, [3]byte{0xc3, 0x8a, 0x00}}, {2, [3]byte{0xc3, 0x8b, 0x00}}, + {2, [3]byte{0xc3, 0x8c, 0x00}}, {2, [3]byte{0xc3, 0x8d, 0x00}}, + {2, [3]byte{0xc3, 0x8e, 0x00}}, {2, [3]byte{0xc3, 0x8f, 0x00}}, + {2, [3]byte{0xc3, 0x90, 0x00}}, {2, [3]byte{0xc3, 0x91, 0x00}}, + {2, [3]byte{0xc3, 0x92, 0x00}}, {2, [3]byte{0xc3, 0x93, 0x00}}, + {2, [3]byte{0xc3, 0x94, 0x00}}, {2, [3]byte{0xc3, 0x95, 0x00}}, + {2, [3]byte{0xc3, 0x96, 0x00}}, {2, [3]byte{0xc3, 0x97, 0x00}}, + {2, [3]byte{0xc3, 0x98, 0x00}}, {2, [3]byte{0xc3, 0x99, 0x00}}, + {2, [3]byte{0xc3, 0x9a, 0x00}}, {2, [3]byte{0xc3, 0x9b, 0x00}}, + {2, [3]byte{0xc3, 0x9c, 0x00}}, {2, [3]byte{0xc3, 0x9d, 0x00}}, + {2, [3]byte{0xc3, 0x9e, 0x00}}, {2, [3]byte{0xc3, 0x9f, 0x00}}, + {2, [3]byte{0xc3, 0xa0, 0x00}}, {2, [3]byte{0xc3, 0xa1, 0x00}}, + {2, [3]byte{0xc3, 0xa2, 0x00}}, {2, [3]byte{0xc3, 0xa3, 0x00}}, + {2, [3]byte{0xc3, 0xa4, 0x00}}, {2, [3]byte{0xc3, 0xa5, 0x00}}, + {2, [3]byte{0xc3, 0xa6, 0x00}}, {2, [3]byte{0xc3, 0xa7, 0x00}}, + {2, [3]byte{0xc3, 0xa8, 0x00}}, {2, [3]byte{0xc3, 0xa9, 0x00}}, + {2, [3]byte{0xc3, 0xaa, 0x00}}, {2, [3]byte{0xc3, 0xab, 0x00}}, + {2, [3]byte{0xc3, 0xac, 0x00}}, {2, [3]byte{0xc3, 0xad, 0x00}}, + {2, [3]byte{0xc3, 0xae, 0x00}}, {2, [3]byte{0xc3, 0xaf, 0x00}}, + {2, [3]byte{0xc3, 0xb0, 0x00}}, {2, [3]byte{0xc3, 0xb1, 0x00}}, + {2, [3]byte{0xc3, 0xb2, 0x00}}, {2, [3]byte{0xc3, 0xb3, 0x00}}, + {2, [3]byte{0xc3, 0xb4, 0x00}}, {2, [3]byte{0xc3, 0xb5, 0x00}}, + {2, [3]byte{0xc3, 0xb6, 0x00}}, {2, [3]byte{0xc3, 0xb7, 0x00}}, + {2, [3]byte{0xc3, 0xb8, 0x00}}, {2, [3]byte{0xc3, 0xb9, 0x00}}, + {2, [3]byte{0xc3, 0xba, 0x00}}, {2, [3]byte{0xc3, 0xbb, 0x00}}, + {2, [3]byte{0xc3, 0xbc, 0x00}}, {2, [3]byte{0xc3, 0xbd, 0x00}}, + {2, [3]byte{0xc3, 0xbe, 0x00}}, {2, [3]byte{0xc3, 0xbf, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0x80000080, 0x81000081, 0x82000082, 0x83000083, 0x84000084, 0x85000085, 0x86000086, 0x87000087, + 0x88000088, 0x89000089, 0x8a00008a, 0x8b00008b, 0x8c00008c, 0x8d00008d, 0x8e00008e, 0x8f00008f, + 0x90000090, 0x91000091, 0x92000092, 0x93000093, 0x94000094, 0x95000095, 0x96000096, 0x97000097, + 0x98000098, 0x99000099, 0x9a00009a, 0x9b00009b, 0x9c00009c, 0x9d00009d, 0x9e00009e, 0x9f00009f, + 0xa00000a0, 0xa10000a1, 0xa20000a2, 0xa30000a3, 0xa40000a4, 0xa50000a5, 0xa60000a6, 0xa70000a7, + 0xa80000a8, 0xa90000a9, 0xaa0000aa, 0xab0000ab, 0xac0000ac, 0xad0000ad, 0xae0000ae, 0xaf0000af, + 0xb00000b0, 0xb10000b1, 0xb20000b2, 0xb30000b3, 0xb40000b4, 0xb50000b5, 0xb60000b6, 0xb70000b7, + 0xb80000b8, 0xb90000b9, 0xba0000ba, 0xbb0000bb, 0xbc0000bc, 0xbd0000bd, 0xbe0000be, 0xbf0000bf, + 0xc00000c0, 0xc10000c1, 0xc20000c2, 0xc30000c3, 0xc40000c4, 0xc50000c5, 0xc60000c6, 0xc70000c7, + 0xc80000c8, 0xc90000c9, 0xca0000ca, 0xcb0000cb, 0xcc0000cc, 0xcd0000cd, 0xce0000ce, 0xcf0000cf, + 0xd00000d0, 0xd10000d1, 0xd20000d2, 0xd30000d3, 0xd40000d4, 0xd50000d5, 0xd60000d6, 0xd70000d7, + 0xd80000d8, 0xd90000d9, 0xda0000da, 0xdb0000db, 0xdc0000dc, 0xdd0000dd, 0xde0000de, 0xdf0000df, + 0xe00000e0, 0xe10000e1, 0xe20000e2, 0xe30000e3, 0xe40000e4, 0xe50000e5, 0xe60000e6, 0xe70000e7, + 0xe80000e8, 0xe90000e9, 0xea0000ea, 0xeb0000eb, 0xec0000ec, 0xed0000ed, 0xee0000ee, 0xef0000ef, + 0xf00000f0, 0xf10000f1, 0xf20000f2, 0xf30000f3, 0xf40000f4, 0xf50000f5, 0xf60000f6, 0xf70000f7, + 0xf80000f8, 0xf90000f9, 0xfa0000fa, 0xfb0000fb, 0xfc0000fc, 0xfd0000fd, 0xfe0000fe, 0xff0000ff, + }, +} + +// ISO8859_2 is the ISO 8859-2 encoding. +var ISO8859_2 *Charmap = &iso8859_2 + +var iso8859_2 = Charmap{ + name: "ISO 8859-2", + mib: identifier.ISOLatin2, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {2, [3]byte{0xc2, 0xa0, 0x00}}, {2, [3]byte{0xc4, 0x84, 0x00}}, + {2, [3]byte{0xcb, 0x98, 0x00}}, {2, [3]byte{0xc5, 0x81, 0x00}}, + {2, [3]byte{0xc2, 0xa4, 0x00}}, {2, [3]byte{0xc4, 0xbd, 0x00}}, + {2, [3]byte{0xc5, 0x9a, 0x00}}, {2, [3]byte{0xc2, 0xa7, 0x00}}, + {2, [3]byte{0xc2, 0xa8, 0x00}}, {2, [3]byte{0xc5, 0xa0, 0x00}}, + {2, [3]byte{0xc5, 0x9e, 0x00}}, {2, [3]byte{0xc5, 0xa4, 0x00}}, + {2, [3]byte{0xc5, 0xb9, 0x00}}, {2, [3]byte{0xc2, 0xad, 0x00}}, + {2, [3]byte{0xc5, 0xbd, 0x00}}, {2, [3]byte{0xc5, 0xbb, 0x00}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {2, [3]byte{0xc4, 0x85, 0x00}}, + {2, [3]byte{0xcb, 0x9b, 0x00}}, {2, [3]byte{0xc5, 0x82, 0x00}}, + {2, [3]byte{0xc2, 0xb4, 0x00}}, {2, [3]byte{0xc4, 0xbe, 0x00}}, + {2, [3]byte{0xc5, 0x9b, 0x00}}, {2, [3]byte{0xcb, 0x87, 0x00}}, + {2, [3]byte{0xc2, 0xb8, 0x00}}, {2, [3]byte{0xc5, 0xa1, 0x00}}, + {2, [3]byte{0xc5, 0x9f, 0x00}}, {2, [3]byte{0xc5, 0xa5, 0x00}}, + {2, [3]byte{0xc5, 0xba, 0x00}}, {2, [3]byte{0xcb, 0x9d, 0x00}}, + {2, [3]byte{0xc5, 0xbe, 0x00}}, {2, [3]byte{0xc5, 0xbc, 0x00}}, + {2, [3]byte{0xc5, 0x94, 0x00}}, {2, [3]byte{0xc3, 0x81, 0x00}}, + {2, [3]byte{0xc3, 0x82, 0x00}}, {2, [3]byte{0xc4, 0x82, 0x00}}, + {2, [3]byte{0xc3, 0x84, 0x00}}, {2, [3]byte{0xc4, 0xb9, 0x00}}, + {2, [3]byte{0xc4, 0x86, 0x00}}, {2, [3]byte{0xc3, 0x87, 0x00}}, + {2, [3]byte{0xc4, 0x8c, 0x00}}, {2, [3]byte{0xc3, 0x89, 0x00}}, + {2, [3]byte{0xc4, 0x98, 0x00}}, {2, [3]byte{0xc3, 0x8b, 0x00}}, + {2, [3]byte{0xc4, 0x9a, 0x00}}, {2, [3]byte{0xc3, 0x8d, 0x00}}, + {2, [3]byte{0xc3, 0x8e, 0x00}}, {2, [3]byte{0xc4, 0x8e, 0x00}}, + {2, [3]byte{0xc4, 0x90, 0x00}}, {2, [3]byte{0xc5, 0x83, 0x00}}, + {2, [3]byte{0xc5, 0x87, 0x00}}, {2, [3]byte{0xc3, 0x93, 0x00}}, + {2, [3]byte{0xc3, 0x94, 0x00}}, {2, [3]byte{0xc5, 0x90, 0x00}}, + {2, [3]byte{0xc3, 0x96, 0x00}}, {2, [3]byte{0xc3, 0x97, 0x00}}, + {2, [3]byte{0xc5, 0x98, 0x00}}, {2, [3]byte{0xc5, 0xae, 0x00}}, + {2, [3]byte{0xc3, 0x9a, 0x00}}, {2, [3]byte{0xc5, 0xb0, 0x00}}, + {2, [3]byte{0xc3, 0x9c, 0x00}}, {2, [3]byte{0xc3, 0x9d, 0x00}}, + {2, [3]byte{0xc5, 0xa2, 0x00}}, {2, [3]byte{0xc3, 0x9f, 0x00}}, + {2, [3]byte{0xc5, 0x95, 0x00}}, {2, [3]byte{0xc3, 0xa1, 0x00}}, + {2, [3]byte{0xc3, 0xa2, 0x00}}, {2, [3]byte{0xc4, 0x83, 0x00}}, + {2, [3]byte{0xc3, 0xa4, 0x00}}, {2, [3]byte{0xc4, 0xba, 0x00}}, + {2, [3]byte{0xc4, 0x87, 0x00}}, {2, [3]byte{0xc3, 0xa7, 0x00}}, + {2, [3]byte{0xc4, 0x8d, 0x00}}, {2, [3]byte{0xc3, 0xa9, 0x00}}, + {2, [3]byte{0xc4, 0x99, 0x00}}, {2, [3]byte{0xc3, 0xab, 0x00}}, + {2, [3]byte{0xc4, 0x9b, 0x00}}, {2, [3]byte{0xc3, 0xad, 0x00}}, + {2, [3]byte{0xc3, 0xae, 0x00}}, {2, [3]byte{0xc4, 0x8f, 0x00}}, + {2, [3]byte{0xc4, 0x91, 0x00}}, {2, [3]byte{0xc5, 0x84, 0x00}}, + {2, [3]byte{0xc5, 0x88, 0x00}}, {2, [3]byte{0xc3, 0xb3, 0x00}}, + {2, [3]byte{0xc3, 0xb4, 0x00}}, {2, [3]byte{0xc5, 0x91, 0x00}}, + {2, [3]byte{0xc3, 0xb6, 0x00}}, {2, [3]byte{0xc3, 0xb7, 0x00}}, + {2, [3]byte{0xc5, 0x99, 0x00}}, {2, [3]byte{0xc5, 0xaf, 0x00}}, + {2, [3]byte{0xc3, 0xba, 0x00}}, {2, [3]byte{0xc5, 0xb1, 0x00}}, + {2, [3]byte{0xc3, 0xbc, 0x00}}, {2, [3]byte{0xc3, 0xbd, 0x00}}, + {2, [3]byte{0xc5, 0xa3, 0x00}}, {2, [3]byte{0xcb, 0x99, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xa00000a0, 0xa40000a4, 0xa70000a7, 0xa80000a8, 0xad0000ad, 0xb00000b0, 0xb40000b4, 0xb80000b8, + 0xc10000c1, 0xc20000c2, 0xc40000c4, 0xc70000c7, 0xc90000c9, 0xcb0000cb, 0xcd0000cd, 0xce0000ce, + 0xd30000d3, 0xd40000d4, 0xd60000d6, 0xd70000d7, 0xda0000da, 0xdc0000dc, 0xdd0000dd, 0xdf0000df, + 0xe10000e1, 0xe20000e2, 0xe40000e4, 0xe70000e7, 0xe90000e9, 0xeb0000eb, 0xed0000ed, 0xee0000ee, + 0xf30000f3, 0xf40000f4, 0xf60000f6, 0xf70000f7, 0xfa0000fa, 0xfc0000fc, 0xfd0000fd, 0xc3000102, + 0xe3000103, 0xa1000104, 0xb1000105, 0xc6000106, 0xe6000107, 0xc800010c, 0xe800010d, 0xcf00010e, + 0xef00010f, 0xd0000110, 0xf0000111, 0xca000118, 0xea000119, 0xcc00011a, 0xec00011b, 0xc5000139, + 0xe500013a, 0xa500013d, 0xb500013e, 0xa3000141, 0xb3000142, 0xd1000143, 0xf1000144, 0xd2000147, + 0xf2000148, 0xd5000150, 0xf5000151, 0xc0000154, 0xe0000155, 0xd8000158, 0xf8000159, 0xa600015a, + 0xb600015b, 0xaa00015e, 0xba00015f, 0xa9000160, 0xb9000161, 0xde000162, 0xfe000163, 0xab000164, + 0xbb000165, 0xd900016e, 0xf900016f, 0xdb000170, 0xfb000171, 0xac000179, 0xbc00017a, 0xaf00017b, + 0xbf00017c, 0xae00017d, 0xbe00017e, 0xb70002c7, 0xa20002d8, 0xff0002d9, 0xb20002db, 0xbd0002dd, + 0xbd0002dd, 0xbd0002dd, 0xbd0002dd, 0xbd0002dd, 0xbd0002dd, 0xbd0002dd, 0xbd0002dd, 0xbd0002dd, + 0xbd0002dd, 0xbd0002dd, 0xbd0002dd, 0xbd0002dd, 0xbd0002dd, 0xbd0002dd, 0xbd0002dd, 0xbd0002dd, + 0xbd0002dd, 0xbd0002dd, 0xbd0002dd, 0xbd0002dd, 0xbd0002dd, 0xbd0002dd, 0xbd0002dd, 0xbd0002dd, + 0xbd0002dd, 0xbd0002dd, 0xbd0002dd, 0xbd0002dd, 0xbd0002dd, 0xbd0002dd, 0xbd0002dd, 0xbd0002dd, + }, +} + +// ISO8859_3 is the ISO 8859-3 encoding. +var ISO8859_3 *Charmap = &iso8859_3 + +var iso8859_3 = Charmap{ + name: "ISO 8859-3", + mib: identifier.ISOLatin3, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {2, [3]byte{0xc2, 0xa0, 0x00}}, {2, [3]byte{0xc4, 0xa6, 0x00}}, + {2, [3]byte{0xcb, 0x98, 0x00}}, {2, [3]byte{0xc2, 0xa3, 0x00}}, + {2, [3]byte{0xc2, 0xa4, 0x00}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {2, [3]byte{0xc4, 0xa4, 0x00}}, {2, [3]byte{0xc2, 0xa7, 0x00}}, + {2, [3]byte{0xc2, 0xa8, 0x00}}, {2, [3]byte{0xc4, 0xb0, 0x00}}, + {2, [3]byte{0xc5, 0x9e, 0x00}}, {2, [3]byte{0xc4, 0x9e, 0x00}}, + {2, [3]byte{0xc4, 0xb4, 0x00}}, {2, [3]byte{0xc2, 0xad, 0x00}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {2, [3]byte{0xc5, 0xbb, 0x00}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {2, [3]byte{0xc4, 0xa7, 0x00}}, + {2, [3]byte{0xc2, 0xb2, 0x00}}, {2, [3]byte{0xc2, 0xb3, 0x00}}, + {2, [3]byte{0xc2, 0xb4, 0x00}}, {2, [3]byte{0xc2, 0xb5, 0x00}}, + {2, [3]byte{0xc4, 0xa5, 0x00}}, {2, [3]byte{0xc2, 0xb7, 0x00}}, + {2, [3]byte{0xc2, 0xb8, 0x00}}, {2, [3]byte{0xc4, 0xb1, 0x00}}, + {2, [3]byte{0xc5, 0x9f, 0x00}}, {2, [3]byte{0xc4, 0x9f, 0x00}}, + {2, [3]byte{0xc4, 0xb5, 0x00}}, {2, [3]byte{0xc2, 0xbd, 0x00}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {2, [3]byte{0xc5, 0xbc, 0x00}}, + {2, [3]byte{0xc3, 0x80, 0x00}}, {2, [3]byte{0xc3, 0x81, 0x00}}, + {2, [3]byte{0xc3, 0x82, 0x00}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {2, [3]byte{0xc3, 0x84, 0x00}}, {2, [3]byte{0xc4, 0x8a, 0x00}}, + {2, [3]byte{0xc4, 0x88, 0x00}}, {2, [3]byte{0xc3, 0x87, 0x00}}, + {2, [3]byte{0xc3, 0x88, 0x00}}, {2, [3]byte{0xc3, 0x89, 0x00}}, + {2, [3]byte{0xc3, 0x8a, 0x00}}, {2, [3]byte{0xc3, 0x8b, 0x00}}, + {2, [3]byte{0xc3, 0x8c, 0x00}}, {2, [3]byte{0xc3, 0x8d, 0x00}}, + {2, [3]byte{0xc3, 0x8e, 0x00}}, {2, [3]byte{0xc3, 0x8f, 0x00}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {2, [3]byte{0xc3, 0x91, 0x00}}, + {2, [3]byte{0xc3, 0x92, 0x00}}, {2, [3]byte{0xc3, 0x93, 0x00}}, + {2, [3]byte{0xc3, 0x94, 0x00}}, {2, [3]byte{0xc4, 0xa0, 0x00}}, + {2, [3]byte{0xc3, 0x96, 0x00}}, {2, [3]byte{0xc3, 0x97, 0x00}}, + {2, [3]byte{0xc4, 0x9c, 0x00}}, {2, [3]byte{0xc3, 0x99, 0x00}}, + {2, [3]byte{0xc3, 0x9a, 0x00}}, {2, [3]byte{0xc3, 0x9b, 0x00}}, + {2, [3]byte{0xc3, 0x9c, 0x00}}, {2, [3]byte{0xc5, 0xac, 0x00}}, + {2, [3]byte{0xc5, 0x9c, 0x00}}, {2, [3]byte{0xc3, 0x9f, 0x00}}, + {2, [3]byte{0xc3, 0xa0, 0x00}}, {2, [3]byte{0xc3, 0xa1, 0x00}}, + {2, [3]byte{0xc3, 0xa2, 0x00}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {2, [3]byte{0xc3, 0xa4, 0x00}}, {2, [3]byte{0xc4, 0x8b, 0x00}}, + {2, [3]byte{0xc4, 0x89, 0x00}}, {2, [3]byte{0xc3, 0xa7, 0x00}}, + {2, [3]byte{0xc3, 0xa8, 0x00}}, {2, [3]byte{0xc3, 0xa9, 0x00}}, + {2, [3]byte{0xc3, 0xaa, 0x00}}, {2, [3]byte{0xc3, 0xab, 0x00}}, + {2, [3]byte{0xc3, 0xac, 0x00}}, {2, [3]byte{0xc3, 0xad, 0x00}}, + {2, [3]byte{0xc3, 0xae, 0x00}}, {2, [3]byte{0xc3, 0xaf, 0x00}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {2, [3]byte{0xc3, 0xb1, 0x00}}, + {2, [3]byte{0xc3, 0xb2, 0x00}}, {2, [3]byte{0xc3, 0xb3, 0x00}}, + {2, [3]byte{0xc3, 0xb4, 0x00}}, {2, [3]byte{0xc4, 0xa1, 0x00}}, + {2, [3]byte{0xc3, 0xb6, 0x00}}, {2, [3]byte{0xc3, 0xb7, 0x00}}, + {2, [3]byte{0xc4, 0x9d, 0x00}}, {2, [3]byte{0xc3, 0xb9, 0x00}}, + {2, [3]byte{0xc3, 0xba, 0x00}}, {2, [3]byte{0xc3, 0xbb, 0x00}}, + {2, [3]byte{0xc3, 0xbc, 0x00}}, {2, [3]byte{0xc5, 0xad, 0x00}}, + {2, [3]byte{0xc5, 0x9d, 0x00}}, {2, [3]byte{0xcb, 0x99, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xa00000a0, 0xa30000a3, 0xa40000a4, 0xa70000a7, 0xa80000a8, 0xad0000ad, 0xb00000b0, 0xb20000b2, + 0xb30000b3, 0xb40000b4, 0xb50000b5, 0xb70000b7, 0xb80000b8, 0xbd0000bd, 0xc00000c0, 0xc10000c1, + 0xc20000c2, 0xc40000c4, 0xc70000c7, 0xc80000c8, 0xc90000c9, 0xca0000ca, 0xcb0000cb, 0xcc0000cc, + 0xcd0000cd, 0xce0000ce, 0xcf0000cf, 0xd10000d1, 0xd20000d2, 0xd30000d3, 0xd40000d4, 0xd60000d6, + 0xd70000d7, 0xd90000d9, 0xda0000da, 0xdb0000db, 0xdc0000dc, 0xdf0000df, 0xe00000e0, 0xe10000e1, + 0xe20000e2, 0xe40000e4, 0xe70000e7, 0xe80000e8, 0xe90000e9, 0xea0000ea, 0xeb0000eb, 0xec0000ec, + 0xed0000ed, 0xee0000ee, 0xef0000ef, 0xf10000f1, 0xf20000f2, 0xf30000f3, 0xf40000f4, 0xf60000f6, + 0xf70000f7, 0xf90000f9, 0xfa0000fa, 0xfb0000fb, 0xfc0000fc, 0xc6000108, 0xe6000109, 0xc500010a, + 0xe500010b, 0xd800011c, 0xf800011d, 0xab00011e, 0xbb00011f, 0xd5000120, 0xf5000121, 0xa6000124, + 0xb6000125, 0xa1000126, 0xb1000127, 0xa9000130, 0xb9000131, 0xac000134, 0xbc000135, 0xde00015c, + 0xfe00015d, 0xaa00015e, 0xba00015f, 0xdd00016c, 0xfd00016d, 0xaf00017b, 0xbf00017c, 0xa20002d8, + 0xff0002d9, 0xff0002d9, 0xff0002d9, 0xff0002d9, 0xff0002d9, 0xff0002d9, 0xff0002d9, 0xff0002d9, + 0xff0002d9, 0xff0002d9, 0xff0002d9, 0xff0002d9, 0xff0002d9, 0xff0002d9, 0xff0002d9, 0xff0002d9, + 0xff0002d9, 0xff0002d9, 0xff0002d9, 0xff0002d9, 0xff0002d9, 0xff0002d9, 0xff0002d9, 0xff0002d9, + 0xff0002d9, 0xff0002d9, 0xff0002d9, 0xff0002d9, 0xff0002d9, 0xff0002d9, 0xff0002d9, 0xff0002d9, + 0xff0002d9, 0xff0002d9, 0xff0002d9, 0xff0002d9, 0xff0002d9, 0xff0002d9, 0xff0002d9, 0xff0002d9, + }, +} + +// ISO8859_4 is the ISO 8859-4 encoding. +var ISO8859_4 *Charmap = &iso8859_4 + +var iso8859_4 = Charmap{ + name: "ISO 8859-4", + mib: identifier.ISOLatin4, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {2, [3]byte{0xc2, 0xa0, 0x00}}, {2, [3]byte{0xc4, 0x84, 0x00}}, + {2, [3]byte{0xc4, 0xb8, 0x00}}, {2, [3]byte{0xc5, 0x96, 0x00}}, + {2, [3]byte{0xc2, 0xa4, 0x00}}, {2, [3]byte{0xc4, 0xa8, 0x00}}, + {2, [3]byte{0xc4, 0xbb, 0x00}}, {2, [3]byte{0xc2, 0xa7, 0x00}}, + {2, [3]byte{0xc2, 0xa8, 0x00}}, {2, [3]byte{0xc5, 0xa0, 0x00}}, + {2, [3]byte{0xc4, 0x92, 0x00}}, {2, [3]byte{0xc4, 0xa2, 0x00}}, + {2, [3]byte{0xc5, 0xa6, 0x00}}, {2, [3]byte{0xc2, 0xad, 0x00}}, + {2, [3]byte{0xc5, 0xbd, 0x00}}, {2, [3]byte{0xc2, 0xaf, 0x00}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {2, [3]byte{0xc4, 0x85, 0x00}}, + {2, [3]byte{0xcb, 0x9b, 0x00}}, {2, [3]byte{0xc5, 0x97, 0x00}}, + {2, [3]byte{0xc2, 0xb4, 0x00}}, {2, [3]byte{0xc4, 0xa9, 0x00}}, + {2, [3]byte{0xc4, 0xbc, 0x00}}, {2, [3]byte{0xcb, 0x87, 0x00}}, + {2, [3]byte{0xc2, 0xb8, 0x00}}, {2, [3]byte{0xc5, 0xa1, 0x00}}, + {2, [3]byte{0xc4, 0x93, 0x00}}, {2, [3]byte{0xc4, 0xa3, 0x00}}, + {2, [3]byte{0xc5, 0xa7, 0x00}}, {2, [3]byte{0xc5, 0x8a, 0x00}}, + {2, [3]byte{0xc5, 0xbe, 0x00}}, {2, [3]byte{0xc5, 0x8b, 0x00}}, + {2, [3]byte{0xc4, 0x80, 0x00}}, {2, [3]byte{0xc3, 0x81, 0x00}}, + {2, [3]byte{0xc3, 0x82, 0x00}}, {2, [3]byte{0xc3, 0x83, 0x00}}, + {2, [3]byte{0xc3, 0x84, 0x00}}, {2, [3]byte{0xc3, 0x85, 0x00}}, + {2, [3]byte{0xc3, 0x86, 0x00}}, {2, [3]byte{0xc4, 0xae, 0x00}}, + {2, [3]byte{0xc4, 0x8c, 0x00}}, {2, [3]byte{0xc3, 0x89, 0x00}}, + {2, [3]byte{0xc4, 0x98, 0x00}}, {2, [3]byte{0xc3, 0x8b, 0x00}}, + {2, [3]byte{0xc4, 0x96, 0x00}}, {2, [3]byte{0xc3, 0x8d, 0x00}}, + {2, [3]byte{0xc3, 0x8e, 0x00}}, {2, [3]byte{0xc4, 0xaa, 0x00}}, + {2, [3]byte{0xc4, 0x90, 0x00}}, {2, [3]byte{0xc5, 0x85, 0x00}}, + {2, [3]byte{0xc5, 0x8c, 0x00}}, {2, [3]byte{0xc4, 0xb6, 0x00}}, + {2, [3]byte{0xc3, 0x94, 0x00}}, {2, [3]byte{0xc3, 0x95, 0x00}}, + {2, [3]byte{0xc3, 0x96, 0x00}}, {2, [3]byte{0xc3, 0x97, 0x00}}, + {2, [3]byte{0xc3, 0x98, 0x00}}, {2, [3]byte{0xc5, 0xb2, 0x00}}, + {2, [3]byte{0xc3, 0x9a, 0x00}}, {2, [3]byte{0xc3, 0x9b, 0x00}}, + {2, [3]byte{0xc3, 0x9c, 0x00}}, {2, [3]byte{0xc5, 0xa8, 0x00}}, + {2, [3]byte{0xc5, 0xaa, 0x00}}, {2, [3]byte{0xc3, 0x9f, 0x00}}, + {2, [3]byte{0xc4, 0x81, 0x00}}, {2, [3]byte{0xc3, 0xa1, 0x00}}, + {2, [3]byte{0xc3, 0xa2, 0x00}}, {2, [3]byte{0xc3, 0xa3, 0x00}}, + {2, [3]byte{0xc3, 0xa4, 0x00}}, {2, [3]byte{0xc3, 0xa5, 0x00}}, + {2, [3]byte{0xc3, 0xa6, 0x00}}, {2, [3]byte{0xc4, 0xaf, 0x00}}, + {2, [3]byte{0xc4, 0x8d, 0x00}}, {2, [3]byte{0xc3, 0xa9, 0x00}}, + {2, [3]byte{0xc4, 0x99, 0x00}}, {2, [3]byte{0xc3, 0xab, 0x00}}, + {2, [3]byte{0xc4, 0x97, 0x00}}, {2, [3]byte{0xc3, 0xad, 0x00}}, + {2, [3]byte{0xc3, 0xae, 0x00}}, {2, [3]byte{0xc4, 0xab, 0x00}}, + {2, [3]byte{0xc4, 0x91, 0x00}}, {2, [3]byte{0xc5, 0x86, 0x00}}, + {2, [3]byte{0xc5, 0x8d, 0x00}}, {2, [3]byte{0xc4, 0xb7, 0x00}}, + {2, [3]byte{0xc3, 0xb4, 0x00}}, {2, [3]byte{0xc3, 0xb5, 0x00}}, + {2, [3]byte{0xc3, 0xb6, 0x00}}, {2, [3]byte{0xc3, 0xb7, 0x00}}, + {2, [3]byte{0xc3, 0xb8, 0x00}}, {2, [3]byte{0xc5, 0xb3, 0x00}}, + {2, [3]byte{0xc3, 0xba, 0x00}}, {2, [3]byte{0xc3, 0xbb, 0x00}}, + {2, [3]byte{0xc3, 0xbc, 0x00}}, {2, [3]byte{0xc5, 0xa9, 0x00}}, + {2, [3]byte{0xc5, 0xab, 0x00}}, {2, [3]byte{0xcb, 0x99, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xa00000a0, 0xa40000a4, 0xa70000a7, 0xa80000a8, 0xad0000ad, 0xaf0000af, 0xb00000b0, 0xb40000b4, + 0xb80000b8, 0xc10000c1, 0xc20000c2, 0xc30000c3, 0xc40000c4, 0xc50000c5, 0xc60000c6, 0xc90000c9, + 0xcb0000cb, 0xcd0000cd, 0xce0000ce, 0xd40000d4, 0xd50000d5, 0xd60000d6, 0xd70000d7, 0xd80000d8, + 0xda0000da, 0xdb0000db, 0xdc0000dc, 0xdf0000df, 0xe10000e1, 0xe20000e2, 0xe30000e3, 0xe40000e4, + 0xe50000e5, 0xe60000e6, 0xe90000e9, 0xeb0000eb, 0xed0000ed, 0xee0000ee, 0xf40000f4, 0xf50000f5, + 0xf60000f6, 0xf70000f7, 0xf80000f8, 0xfa0000fa, 0xfb0000fb, 0xfc0000fc, 0xc0000100, 0xe0000101, + 0xa1000104, 0xb1000105, 0xc800010c, 0xe800010d, 0xd0000110, 0xf0000111, 0xaa000112, 0xba000113, + 0xcc000116, 0xec000117, 0xca000118, 0xea000119, 0xab000122, 0xbb000123, 0xa5000128, 0xb5000129, + 0xcf00012a, 0xef00012b, 0xc700012e, 0xe700012f, 0xd3000136, 0xf3000137, 0xa2000138, 0xa600013b, + 0xb600013c, 0xd1000145, 0xf1000146, 0xbd00014a, 0xbf00014b, 0xd200014c, 0xf200014d, 0xa3000156, + 0xb3000157, 0xa9000160, 0xb9000161, 0xac000166, 0xbc000167, 0xdd000168, 0xfd000169, 0xde00016a, + 0xfe00016b, 0xd9000172, 0xf9000173, 0xae00017d, 0xbe00017e, 0xb70002c7, 0xff0002d9, 0xb20002db, + 0xb20002db, 0xb20002db, 0xb20002db, 0xb20002db, 0xb20002db, 0xb20002db, 0xb20002db, 0xb20002db, + 0xb20002db, 0xb20002db, 0xb20002db, 0xb20002db, 0xb20002db, 0xb20002db, 0xb20002db, 0xb20002db, + 0xb20002db, 0xb20002db, 0xb20002db, 0xb20002db, 0xb20002db, 0xb20002db, 0xb20002db, 0xb20002db, + 0xb20002db, 0xb20002db, 0xb20002db, 0xb20002db, 0xb20002db, 0xb20002db, 0xb20002db, 0xb20002db, + }, +} + +// ISO8859_5 is the ISO 8859-5 encoding. +var ISO8859_5 *Charmap = &iso8859_5 + +var iso8859_5 = Charmap{ + name: "ISO 8859-5", + mib: identifier.ISOLatinCyrillic, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {2, [3]byte{0xc2, 0xa0, 0x00}}, {2, [3]byte{0xd0, 0x81, 0x00}}, + {2, [3]byte{0xd0, 0x82, 0x00}}, {2, [3]byte{0xd0, 0x83, 0x00}}, + {2, [3]byte{0xd0, 0x84, 0x00}}, {2, [3]byte{0xd0, 0x85, 0x00}}, + {2, [3]byte{0xd0, 0x86, 0x00}}, {2, [3]byte{0xd0, 0x87, 0x00}}, + {2, [3]byte{0xd0, 0x88, 0x00}}, {2, [3]byte{0xd0, 0x89, 0x00}}, + {2, [3]byte{0xd0, 0x8a, 0x00}}, {2, [3]byte{0xd0, 0x8b, 0x00}}, + {2, [3]byte{0xd0, 0x8c, 0x00}}, {2, [3]byte{0xc2, 0xad, 0x00}}, + {2, [3]byte{0xd0, 0x8e, 0x00}}, {2, [3]byte{0xd0, 0x8f, 0x00}}, + {2, [3]byte{0xd0, 0x90, 0x00}}, {2, [3]byte{0xd0, 0x91, 0x00}}, + {2, [3]byte{0xd0, 0x92, 0x00}}, {2, [3]byte{0xd0, 0x93, 0x00}}, + {2, [3]byte{0xd0, 0x94, 0x00}}, {2, [3]byte{0xd0, 0x95, 0x00}}, + {2, [3]byte{0xd0, 0x96, 0x00}}, {2, [3]byte{0xd0, 0x97, 0x00}}, + {2, [3]byte{0xd0, 0x98, 0x00}}, {2, [3]byte{0xd0, 0x99, 0x00}}, + {2, [3]byte{0xd0, 0x9a, 0x00}}, {2, [3]byte{0xd0, 0x9b, 0x00}}, + {2, [3]byte{0xd0, 0x9c, 0x00}}, {2, [3]byte{0xd0, 0x9d, 0x00}}, + {2, [3]byte{0xd0, 0x9e, 0x00}}, {2, [3]byte{0xd0, 0x9f, 0x00}}, + {2, [3]byte{0xd0, 0xa0, 0x00}}, {2, [3]byte{0xd0, 0xa1, 0x00}}, + {2, [3]byte{0xd0, 0xa2, 0x00}}, {2, [3]byte{0xd0, 0xa3, 0x00}}, + {2, [3]byte{0xd0, 0xa4, 0x00}}, {2, [3]byte{0xd0, 0xa5, 0x00}}, + {2, [3]byte{0xd0, 0xa6, 0x00}}, {2, [3]byte{0xd0, 0xa7, 0x00}}, + {2, [3]byte{0xd0, 0xa8, 0x00}}, {2, [3]byte{0xd0, 0xa9, 0x00}}, + {2, [3]byte{0xd0, 0xaa, 0x00}}, {2, [3]byte{0xd0, 0xab, 0x00}}, + {2, [3]byte{0xd0, 0xac, 0x00}}, {2, [3]byte{0xd0, 0xad, 0x00}}, + {2, [3]byte{0xd0, 0xae, 0x00}}, {2, [3]byte{0xd0, 0xaf, 0x00}}, + {2, [3]byte{0xd0, 0xb0, 0x00}}, {2, [3]byte{0xd0, 0xb1, 0x00}}, + {2, [3]byte{0xd0, 0xb2, 0x00}}, {2, [3]byte{0xd0, 0xb3, 0x00}}, + {2, [3]byte{0xd0, 0xb4, 0x00}}, {2, [3]byte{0xd0, 0xb5, 0x00}}, + {2, [3]byte{0xd0, 0xb6, 0x00}}, {2, [3]byte{0xd0, 0xb7, 0x00}}, + {2, [3]byte{0xd0, 0xb8, 0x00}}, {2, [3]byte{0xd0, 0xb9, 0x00}}, + {2, [3]byte{0xd0, 0xba, 0x00}}, {2, [3]byte{0xd0, 0xbb, 0x00}}, + {2, [3]byte{0xd0, 0xbc, 0x00}}, {2, [3]byte{0xd0, 0xbd, 0x00}}, + {2, [3]byte{0xd0, 0xbe, 0x00}}, {2, [3]byte{0xd0, 0xbf, 0x00}}, + {2, [3]byte{0xd1, 0x80, 0x00}}, {2, [3]byte{0xd1, 0x81, 0x00}}, + {2, [3]byte{0xd1, 0x82, 0x00}}, {2, [3]byte{0xd1, 0x83, 0x00}}, + {2, [3]byte{0xd1, 0x84, 0x00}}, {2, [3]byte{0xd1, 0x85, 0x00}}, + {2, [3]byte{0xd1, 0x86, 0x00}}, {2, [3]byte{0xd1, 0x87, 0x00}}, + {2, [3]byte{0xd1, 0x88, 0x00}}, {2, [3]byte{0xd1, 0x89, 0x00}}, + {2, [3]byte{0xd1, 0x8a, 0x00}}, {2, [3]byte{0xd1, 0x8b, 0x00}}, + {2, [3]byte{0xd1, 0x8c, 0x00}}, {2, [3]byte{0xd1, 0x8d, 0x00}}, + {2, [3]byte{0xd1, 0x8e, 0x00}}, {2, [3]byte{0xd1, 0x8f, 0x00}}, + {3, [3]byte{0xe2, 0x84, 0x96}}, {2, [3]byte{0xd1, 0x91, 0x00}}, + {2, [3]byte{0xd1, 0x92, 0x00}}, {2, [3]byte{0xd1, 0x93, 0x00}}, + {2, [3]byte{0xd1, 0x94, 0x00}}, {2, [3]byte{0xd1, 0x95, 0x00}}, + {2, [3]byte{0xd1, 0x96, 0x00}}, {2, [3]byte{0xd1, 0x97, 0x00}}, + {2, [3]byte{0xd1, 0x98, 0x00}}, {2, [3]byte{0xd1, 0x99, 0x00}}, + {2, [3]byte{0xd1, 0x9a, 0x00}}, {2, [3]byte{0xd1, 0x9b, 0x00}}, + {2, [3]byte{0xd1, 0x9c, 0x00}}, {2, [3]byte{0xc2, 0xa7, 0x00}}, + {2, [3]byte{0xd1, 0x9e, 0x00}}, {2, [3]byte{0xd1, 0x9f, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xa00000a0, 0xfd0000a7, 0xad0000ad, 0xa1000401, 0xa2000402, 0xa3000403, 0xa4000404, 0xa5000405, + 0xa6000406, 0xa7000407, 0xa8000408, 0xa9000409, 0xaa00040a, 0xab00040b, 0xac00040c, 0xae00040e, + 0xaf00040f, 0xb0000410, 0xb1000411, 0xb2000412, 0xb3000413, 0xb4000414, 0xb5000415, 0xb6000416, + 0xb7000417, 0xb8000418, 0xb9000419, 0xba00041a, 0xbb00041b, 0xbc00041c, 0xbd00041d, 0xbe00041e, + 0xbf00041f, 0xc0000420, 0xc1000421, 0xc2000422, 0xc3000423, 0xc4000424, 0xc5000425, 0xc6000426, + 0xc7000427, 0xc8000428, 0xc9000429, 0xca00042a, 0xcb00042b, 0xcc00042c, 0xcd00042d, 0xce00042e, + 0xcf00042f, 0xd0000430, 0xd1000431, 0xd2000432, 0xd3000433, 0xd4000434, 0xd5000435, 0xd6000436, + 0xd7000437, 0xd8000438, 0xd9000439, 0xda00043a, 0xdb00043b, 0xdc00043c, 0xdd00043d, 0xde00043e, + 0xdf00043f, 0xe0000440, 0xe1000441, 0xe2000442, 0xe3000443, 0xe4000444, 0xe5000445, 0xe6000446, + 0xe7000447, 0xe8000448, 0xe9000449, 0xea00044a, 0xeb00044b, 0xec00044c, 0xed00044d, 0xee00044e, + 0xef00044f, 0xf1000451, 0xf2000452, 0xf3000453, 0xf4000454, 0xf5000455, 0xf6000456, 0xf7000457, + 0xf8000458, 0xf9000459, 0xfa00045a, 0xfb00045b, 0xfc00045c, 0xfe00045e, 0xff00045f, 0xf0002116, + 0xf0002116, 0xf0002116, 0xf0002116, 0xf0002116, 0xf0002116, 0xf0002116, 0xf0002116, 0xf0002116, + 0xf0002116, 0xf0002116, 0xf0002116, 0xf0002116, 0xf0002116, 0xf0002116, 0xf0002116, 0xf0002116, + 0xf0002116, 0xf0002116, 0xf0002116, 0xf0002116, 0xf0002116, 0xf0002116, 0xf0002116, 0xf0002116, + 0xf0002116, 0xf0002116, 0xf0002116, 0xf0002116, 0xf0002116, 0xf0002116, 0xf0002116, 0xf0002116, + }, +} + +// ISO8859_6 is the ISO 8859-6 encoding. +var ISO8859_6 *Charmap = &iso8859_6 + +var iso8859_6 = Charmap{ + name: "ISO 8859-6", + mib: identifier.ISOLatinArabic, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {2, [3]byte{0xc2, 0xa0, 0x00}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {2, [3]byte{0xc2, 0xa4, 0x00}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {2, [3]byte{0xd8, 0x8c, 0x00}}, {2, [3]byte{0xc2, 0xad, 0x00}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {2, [3]byte{0xd8, 0x9b, 0x00}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {2, [3]byte{0xd8, 0x9f, 0x00}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {2, [3]byte{0xd8, 0xa1, 0x00}}, + {2, [3]byte{0xd8, 0xa2, 0x00}}, {2, [3]byte{0xd8, 0xa3, 0x00}}, + {2, [3]byte{0xd8, 0xa4, 0x00}}, {2, [3]byte{0xd8, 0xa5, 0x00}}, + {2, [3]byte{0xd8, 0xa6, 0x00}}, {2, [3]byte{0xd8, 0xa7, 0x00}}, + {2, [3]byte{0xd8, 0xa8, 0x00}}, {2, [3]byte{0xd8, 0xa9, 0x00}}, + {2, [3]byte{0xd8, 0xaa, 0x00}}, {2, [3]byte{0xd8, 0xab, 0x00}}, + {2, [3]byte{0xd8, 0xac, 0x00}}, {2, [3]byte{0xd8, 0xad, 0x00}}, + {2, [3]byte{0xd8, 0xae, 0x00}}, {2, [3]byte{0xd8, 0xaf, 0x00}}, + {2, [3]byte{0xd8, 0xb0, 0x00}}, {2, [3]byte{0xd8, 0xb1, 0x00}}, + {2, [3]byte{0xd8, 0xb2, 0x00}}, {2, [3]byte{0xd8, 0xb3, 0x00}}, + {2, [3]byte{0xd8, 0xb4, 0x00}}, {2, [3]byte{0xd8, 0xb5, 0x00}}, + {2, [3]byte{0xd8, 0xb6, 0x00}}, {2, [3]byte{0xd8, 0xb7, 0x00}}, + {2, [3]byte{0xd8, 0xb8, 0x00}}, {2, [3]byte{0xd8, 0xb9, 0x00}}, + {2, [3]byte{0xd8, 0xba, 0x00}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {2, [3]byte{0xd9, 0x80, 0x00}}, {2, [3]byte{0xd9, 0x81, 0x00}}, + {2, [3]byte{0xd9, 0x82, 0x00}}, {2, [3]byte{0xd9, 0x83, 0x00}}, + {2, [3]byte{0xd9, 0x84, 0x00}}, {2, [3]byte{0xd9, 0x85, 0x00}}, + {2, [3]byte{0xd9, 0x86, 0x00}}, {2, [3]byte{0xd9, 0x87, 0x00}}, + {2, [3]byte{0xd9, 0x88, 0x00}}, {2, [3]byte{0xd9, 0x89, 0x00}}, + {2, [3]byte{0xd9, 0x8a, 0x00}}, {2, [3]byte{0xd9, 0x8b, 0x00}}, + {2, [3]byte{0xd9, 0x8c, 0x00}}, {2, [3]byte{0xd9, 0x8d, 0x00}}, + {2, [3]byte{0xd9, 0x8e, 0x00}}, {2, [3]byte{0xd9, 0x8f, 0x00}}, + {2, [3]byte{0xd9, 0x90, 0x00}}, {2, [3]byte{0xd9, 0x91, 0x00}}, + {2, [3]byte{0xd9, 0x92, 0x00}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xa00000a0, 0xa40000a4, 0xad0000ad, 0xac00060c, 0xbb00061b, 0xbf00061f, 0xc1000621, 0xc2000622, + 0xc3000623, 0xc4000624, 0xc5000625, 0xc6000626, 0xc7000627, 0xc8000628, 0xc9000629, 0xca00062a, + 0xcb00062b, 0xcc00062c, 0xcd00062d, 0xce00062e, 0xcf00062f, 0xd0000630, 0xd1000631, 0xd2000632, + 0xd3000633, 0xd4000634, 0xd5000635, 0xd6000636, 0xd7000637, 0xd8000638, 0xd9000639, 0xda00063a, + 0xe0000640, 0xe1000641, 0xe2000642, 0xe3000643, 0xe4000644, 0xe5000645, 0xe6000646, 0xe7000647, + 0xe8000648, 0xe9000649, 0xea00064a, 0xeb00064b, 0xec00064c, 0xed00064d, 0xee00064e, 0xef00064f, + 0xf0000650, 0xf1000651, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, + 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, + 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, + 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, + 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, + 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, + 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, + 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, + 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, + 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, 0xf2000652, + }, +} + +// ISO8859_7 is the ISO 8859-7 encoding. +var ISO8859_7 *Charmap = &iso8859_7 + +var iso8859_7 = Charmap{ + name: "ISO 8859-7", + mib: identifier.ISOLatinGreek, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {2, [3]byte{0xc2, 0xa0, 0x00}}, {3, [3]byte{0xe2, 0x80, 0x98}}, + {3, [3]byte{0xe2, 0x80, 0x99}}, {2, [3]byte{0xc2, 0xa3, 0x00}}, + {3, [3]byte{0xe2, 0x82, 0xac}}, {3, [3]byte{0xe2, 0x82, 0xaf}}, + {2, [3]byte{0xc2, 0xa6, 0x00}}, {2, [3]byte{0xc2, 0xa7, 0x00}}, + {2, [3]byte{0xc2, 0xa8, 0x00}}, {2, [3]byte{0xc2, 0xa9, 0x00}}, + {2, [3]byte{0xcd, 0xba, 0x00}}, {2, [3]byte{0xc2, 0xab, 0x00}}, + {2, [3]byte{0xc2, 0xac, 0x00}}, {2, [3]byte{0xc2, 0xad, 0x00}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xe2, 0x80, 0x95}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {2, [3]byte{0xc2, 0xb1, 0x00}}, + {2, [3]byte{0xc2, 0xb2, 0x00}}, {2, [3]byte{0xc2, 0xb3, 0x00}}, + {2, [3]byte{0xce, 0x84, 0x00}}, {2, [3]byte{0xce, 0x85, 0x00}}, + {2, [3]byte{0xce, 0x86, 0x00}}, {2, [3]byte{0xc2, 0xb7, 0x00}}, + {2, [3]byte{0xce, 0x88, 0x00}}, {2, [3]byte{0xce, 0x89, 0x00}}, + {2, [3]byte{0xce, 0x8a, 0x00}}, {2, [3]byte{0xc2, 0xbb, 0x00}}, + {2, [3]byte{0xce, 0x8c, 0x00}}, {2, [3]byte{0xc2, 0xbd, 0x00}}, + {2, [3]byte{0xce, 0x8e, 0x00}}, {2, [3]byte{0xce, 0x8f, 0x00}}, + {2, [3]byte{0xce, 0x90, 0x00}}, {2, [3]byte{0xce, 0x91, 0x00}}, + {2, [3]byte{0xce, 0x92, 0x00}}, {2, [3]byte{0xce, 0x93, 0x00}}, + {2, [3]byte{0xce, 0x94, 0x00}}, {2, [3]byte{0xce, 0x95, 0x00}}, + {2, [3]byte{0xce, 0x96, 0x00}}, {2, [3]byte{0xce, 0x97, 0x00}}, + {2, [3]byte{0xce, 0x98, 0x00}}, {2, [3]byte{0xce, 0x99, 0x00}}, + {2, [3]byte{0xce, 0x9a, 0x00}}, {2, [3]byte{0xce, 0x9b, 0x00}}, + {2, [3]byte{0xce, 0x9c, 0x00}}, {2, [3]byte{0xce, 0x9d, 0x00}}, + {2, [3]byte{0xce, 0x9e, 0x00}}, {2, [3]byte{0xce, 0x9f, 0x00}}, + {2, [3]byte{0xce, 0xa0, 0x00}}, {2, [3]byte{0xce, 0xa1, 0x00}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {2, [3]byte{0xce, 0xa3, 0x00}}, + {2, [3]byte{0xce, 0xa4, 0x00}}, {2, [3]byte{0xce, 0xa5, 0x00}}, + {2, [3]byte{0xce, 0xa6, 0x00}}, {2, [3]byte{0xce, 0xa7, 0x00}}, + {2, [3]byte{0xce, 0xa8, 0x00}}, {2, [3]byte{0xce, 0xa9, 0x00}}, + {2, [3]byte{0xce, 0xaa, 0x00}}, {2, [3]byte{0xce, 0xab, 0x00}}, + {2, [3]byte{0xce, 0xac, 0x00}}, {2, [3]byte{0xce, 0xad, 0x00}}, + {2, [3]byte{0xce, 0xae, 0x00}}, {2, [3]byte{0xce, 0xaf, 0x00}}, + {2, [3]byte{0xce, 0xb0, 0x00}}, {2, [3]byte{0xce, 0xb1, 0x00}}, + {2, [3]byte{0xce, 0xb2, 0x00}}, {2, [3]byte{0xce, 0xb3, 0x00}}, + {2, [3]byte{0xce, 0xb4, 0x00}}, {2, [3]byte{0xce, 0xb5, 0x00}}, + {2, [3]byte{0xce, 0xb6, 0x00}}, {2, [3]byte{0xce, 0xb7, 0x00}}, + {2, [3]byte{0xce, 0xb8, 0x00}}, {2, [3]byte{0xce, 0xb9, 0x00}}, + {2, [3]byte{0xce, 0xba, 0x00}}, {2, [3]byte{0xce, 0xbb, 0x00}}, + {2, [3]byte{0xce, 0xbc, 0x00}}, {2, [3]byte{0xce, 0xbd, 0x00}}, + {2, [3]byte{0xce, 0xbe, 0x00}}, {2, [3]byte{0xce, 0xbf, 0x00}}, + {2, [3]byte{0xcf, 0x80, 0x00}}, {2, [3]byte{0xcf, 0x81, 0x00}}, + {2, [3]byte{0xcf, 0x82, 0x00}}, {2, [3]byte{0xcf, 0x83, 0x00}}, + {2, [3]byte{0xcf, 0x84, 0x00}}, {2, [3]byte{0xcf, 0x85, 0x00}}, + {2, [3]byte{0xcf, 0x86, 0x00}}, {2, [3]byte{0xcf, 0x87, 0x00}}, + {2, [3]byte{0xcf, 0x88, 0x00}}, {2, [3]byte{0xcf, 0x89, 0x00}}, + {2, [3]byte{0xcf, 0x8a, 0x00}}, {2, [3]byte{0xcf, 0x8b, 0x00}}, + {2, [3]byte{0xcf, 0x8c, 0x00}}, {2, [3]byte{0xcf, 0x8d, 0x00}}, + {2, [3]byte{0xcf, 0x8e, 0x00}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xa00000a0, 0xa30000a3, 0xa60000a6, 0xa70000a7, 0xa80000a8, 0xa90000a9, 0xab0000ab, 0xac0000ac, + 0xad0000ad, 0xb00000b0, 0xb10000b1, 0xb20000b2, 0xb30000b3, 0xb70000b7, 0xbb0000bb, 0xbd0000bd, + 0xaa00037a, 0xb4000384, 0xb5000385, 0xb6000386, 0xb8000388, 0xb9000389, 0xba00038a, 0xbc00038c, + 0xbe00038e, 0xbf00038f, 0xc0000390, 0xc1000391, 0xc2000392, 0xc3000393, 0xc4000394, 0xc5000395, + 0xc6000396, 0xc7000397, 0xc8000398, 0xc9000399, 0xca00039a, 0xcb00039b, 0xcc00039c, 0xcd00039d, + 0xce00039e, 0xcf00039f, 0xd00003a0, 0xd10003a1, 0xd30003a3, 0xd40003a4, 0xd50003a5, 0xd60003a6, + 0xd70003a7, 0xd80003a8, 0xd90003a9, 0xda0003aa, 0xdb0003ab, 0xdc0003ac, 0xdd0003ad, 0xde0003ae, + 0xdf0003af, 0xe00003b0, 0xe10003b1, 0xe20003b2, 0xe30003b3, 0xe40003b4, 0xe50003b5, 0xe60003b6, + 0xe70003b7, 0xe80003b8, 0xe90003b9, 0xea0003ba, 0xeb0003bb, 0xec0003bc, 0xed0003bd, 0xee0003be, + 0xef0003bf, 0xf00003c0, 0xf10003c1, 0xf20003c2, 0xf30003c3, 0xf40003c4, 0xf50003c5, 0xf60003c6, + 0xf70003c7, 0xf80003c8, 0xf90003c9, 0xfa0003ca, 0xfb0003cb, 0xfc0003cc, 0xfd0003cd, 0xfe0003ce, + 0xaf002015, 0xa1002018, 0xa2002019, 0xa40020ac, 0xa50020af, 0xa50020af, 0xa50020af, 0xa50020af, + 0xa50020af, 0xa50020af, 0xa50020af, 0xa50020af, 0xa50020af, 0xa50020af, 0xa50020af, 0xa50020af, + 0xa50020af, 0xa50020af, 0xa50020af, 0xa50020af, 0xa50020af, 0xa50020af, 0xa50020af, 0xa50020af, + 0xa50020af, 0xa50020af, 0xa50020af, 0xa50020af, 0xa50020af, 0xa50020af, 0xa50020af, 0xa50020af, + 0xa50020af, 0xa50020af, 0xa50020af, 0xa50020af, 0xa50020af, 0xa50020af, 0xa50020af, 0xa50020af, + }, +} + +// ISO8859_8 is the ISO 8859-8 encoding. +var ISO8859_8 *Charmap = &iso8859_8 + +var iso8859_8 = Charmap{ + name: "ISO 8859-8", + mib: identifier.ISOLatinHebrew, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {2, [3]byte{0xc2, 0xa0, 0x00}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {2, [3]byte{0xc2, 0xa2, 0x00}}, {2, [3]byte{0xc2, 0xa3, 0x00}}, + {2, [3]byte{0xc2, 0xa4, 0x00}}, {2, [3]byte{0xc2, 0xa5, 0x00}}, + {2, [3]byte{0xc2, 0xa6, 0x00}}, {2, [3]byte{0xc2, 0xa7, 0x00}}, + {2, [3]byte{0xc2, 0xa8, 0x00}}, {2, [3]byte{0xc2, 0xa9, 0x00}}, + {2, [3]byte{0xc3, 0x97, 0x00}}, {2, [3]byte{0xc2, 0xab, 0x00}}, + {2, [3]byte{0xc2, 0xac, 0x00}}, {2, [3]byte{0xc2, 0xad, 0x00}}, + {2, [3]byte{0xc2, 0xae, 0x00}}, {2, [3]byte{0xc2, 0xaf, 0x00}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {2, [3]byte{0xc2, 0xb1, 0x00}}, + {2, [3]byte{0xc2, 0xb2, 0x00}}, {2, [3]byte{0xc2, 0xb3, 0x00}}, + {2, [3]byte{0xc2, 0xb4, 0x00}}, {2, [3]byte{0xc2, 0xb5, 0x00}}, + {2, [3]byte{0xc2, 0xb6, 0x00}}, {2, [3]byte{0xc2, 0xb7, 0x00}}, + {2, [3]byte{0xc2, 0xb8, 0x00}}, {2, [3]byte{0xc2, 0xb9, 0x00}}, + {2, [3]byte{0xc3, 0xb7, 0x00}}, {2, [3]byte{0xc2, 0xbb, 0x00}}, + {2, [3]byte{0xc2, 0xbc, 0x00}}, {2, [3]byte{0xc2, 0xbd, 0x00}}, + {2, [3]byte{0xc2, 0xbe, 0x00}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xe2, 0x80, 0x97}}, + {2, [3]byte{0xd7, 0x90, 0x00}}, {2, [3]byte{0xd7, 0x91, 0x00}}, + {2, [3]byte{0xd7, 0x92, 0x00}}, {2, [3]byte{0xd7, 0x93, 0x00}}, + {2, [3]byte{0xd7, 0x94, 0x00}}, {2, [3]byte{0xd7, 0x95, 0x00}}, + {2, [3]byte{0xd7, 0x96, 0x00}}, {2, [3]byte{0xd7, 0x97, 0x00}}, + {2, [3]byte{0xd7, 0x98, 0x00}}, {2, [3]byte{0xd7, 0x99, 0x00}}, + {2, [3]byte{0xd7, 0x9a, 0x00}}, {2, [3]byte{0xd7, 0x9b, 0x00}}, + {2, [3]byte{0xd7, 0x9c, 0x00}}, {2, [3]byte{0xd7, 0x9d, 0x00}}, + {2, [3]byte{0xd7, 0x9e, 0x00}}, {2, [3]byte{0xd7, 0x9f, 0x00}}, + {2, [3]byte{0xd7, 0xa0, 0x00}}, {2, [3]byte{0xd7, 0xa1, 0x00}}, + {2, [3]byte{0xd7, 0xa2, 0x00}}, {2, [3]byte{0xd7, 0xa3, 0x00}}, + {2, [3]byte{0xd7, 0xa4, 0x00}}, {2, [3]byte{0xd7, 0xa5, 0x00}}, + {2, [3]byte{0xd7, 0xa6, 0x00}}, {2, [3]byte{0xd7, 0xa7, 0x00}}, + {2, [3]byte{0xd7, 0xa8, 0x00}}, {2, [3]byte{0xd7, 0xa9, 0x00}}, + {2, [3]byte{0xd7, 0xaa, 0x00}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xe2, 0x80, 0x8e}}, + {3, [3]byte{0xe2, 0x80, 0x8f}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xa00000a0, 0xa20000a2, 0xa30000a3, 0xa40000a4, 0xa50000a5, 0xa60000a6, 0xa70000a7, 0xa80000a8, + 0xa90000a9, 0xab0000ab, 0xac0000ac, 0xad0000ad, 0xae0000ae, 0xaf0000af, 0xb00000b0, 0xb10000b1, + 0xb20000b2, 0xb30000b3, 0xb40000b4, 0xb50000b5, 0xb60000b6, 0xb70000b7, 0xb80000b8, 0xb90000b9, + 0xbb0000bb, 0xbc0000bc, 0xbd0000bd, 0xbe0000be, 0xaa0000d7, 0xba0000f7, 0xe00005d0, 0xe10005d1, + 0xe20005d2, 0xe30005d3, 0xe40005d4, 0xe50005d5, 0xe60005d6, 0xe70005d7, 0xe80005d8, 0xe90005d9, + 0xea0005da, 0xeb0005db, 0xec0005dc, 0xed0005dd, 0xee0005de, 0xef0005df, 0xf00005e0, 0xf10005e1, + 0xf20005e2, 0xf30005e3, 0xf40005e4, 0xf50005e5, 0xf60005e6, 0xf70005e7, 0xf80005e8, 0xf90005e9, + 0xfa0005ea, 0xfd00200e, 0xfe00200f, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, + 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, + 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, + 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, + 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, + 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, + 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, + 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, + 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, 0xdf002017, + }, +} + +// ISO8859_9 is the ISO 8859-9 encoding. +var ISO8859_9 *Charmap = &iso8859_9 + +var iso8859_9 = Charmap{ + name: "ISO 8859-9", + mib: identifier.ISOLatin5, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {2, [3]byte{0xc2, 0x80, 0x00}}, {2, [3]byte{0xc2, 0x81, 0x00}}, + {2, [3]byte{0xc2, 0x82, 0x00}}, {2, [3]byte{0xc2, 0x83, 0x00}}, + {2, [3]byte{0xc2, 0x84, 0x00}}, {2, [3]byte{0xc2, 0x85, 0x00}}, + {2, [3]byte{0xc2, 0x86, 0x00}}, {2, [3]byte{0xc2, 0x87, 0x00}}, + {2, [3]byte{0xc2, 0x88, 0x00}}, {2, [3]byte{0xc2, 0x89, 0x00}}, + {2, [3]byte{0xc2, 0x8a, 0x00}}, {2, [3]byte{0xc2, 0x8b, 0x00}}, + {2, [3]byte{0xc2, 0x8c, 0x00}}, {2, [3]byte{0xc2, 0x8d, 0x00}}, + {2, [3]byte{0xc2, 0x8e, 0x00}}, {2, [3]byte{0xc2, 0x8f, 0x00}}, + {2, [3]byte{0xc2, 0x90, 0x00}}, {2, [3]byte{0xc2, 0x91, 0x00}}, + {2, [3]byte{0xc2, 0x92, 0x00}}, {2, [3]byte{0xc2, 0x93, 0x00}}, + {2, [3]byte{0xc2, 0x94, 0x00}}, {2, [3]byte{0xc2, 0x95, 0x00}}, + {2, [3]byte{0xc2, 0x96, 0x00}}, {2, [3]byte{0xc2, 0x97, 0x00}}, + {2, [3]byte{0xc2, 0x98, 0x00}}, {2, [3]byte{0xc2, 0x99, 0x00}}, + {2, [3]byte{0xc2, 0x9a, 0x00}}, {2, [3]byte{0xc2, 0x9b, 0x00}}, + {2, [3]byte{0xc2, 0x9c, 0x00}}, {2, [3]byte{0xc2, 0x9d, 0x00}}, + {2, [3]byte{0xc2, 0x9e, 0x00}}, {2, [3]byte{0xc2, 0x9f, 0x00}}, + {2, [3]byte{0xc2, 0xa0, 0x00}}, {2, [3]byte{0xc2, 0xa1, 0x00}}, + {2, [3]byte{0xc2, 0xa2, 0x00}}, {2, [3]byte{0xc2, 0xa3, 0x00}}, + {2, [3]byte{0xc2, 0xa4, 0x00}}, {2, [3]byte{0xc2, 0xa5, 0x00}}, + {2, [3]byte{0xc2, 0xa6, 0x00}}, {2, [3]byte{0xc2, 0xa7, 0x00}}, + {2, [3]byte{0xc2, 0xa8, 0x00}}, {2, [3]byte{0xc2, 0xa9, 0x00}}, + {2, [3]byte{0xc2, 0xaa, 0x00}}, {2, [3]byte{0xc2, 0xab, 0x00}}, + {2, [3]byte{0xc2, 0xac, 0x00}}, {2, [3]byte{0xc2, 0xad, 0x00}}, + {2, [3]byte{0xc2, 0xae, 0x00}}, {2, [3]byte{0xc2, 0xaf, 0x00}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {2, [3]byte{0xc2, 0xb1, 0x00}}, + {2, [3]byte{0xc2, 0xb2, 0x00}}, {2, [3]byte{0xc2, 0xb3, 0x00}}, + {2, [3]byte{0xc2, 0xb4, 0x00}}, {2, [3]byte{0xc2, 0xb5, 0x00}}, + {2, [3]byte{0xc2, 0xb6, 0x00}}, {2, [3]byte{0xc2, 0xb7, 0x00}}, + {2, [3]byte{0xc2, 0xb8, 0x00}}, {2, [3]byte{0xc2, 0xb9, 0x00}}, + {2, [3]byte{0xc2, 0xba, 0x00}}, {2, [3]byte{0xc2, 0xbb, 0x00}}, + {2, [3]byte{0xc2, 0xbc, 0x00}}, {2, [3]byte{0xc2, 0xbd, 0x00}}, + {2, [3]byte{0xc2, 0xbe, 0x00}}, {2, [3]byte{0xc2, 0xbf, 0x00}}, + {2, [3]byte{0xc3, 0x80, 0x00}}, {2, [3]byte{0xc3, 0x81, 0x00}}, + {2, [3]byte{0xc3, 0x82, 0x00}}, {2, [3]byte{0xc3, 0x83, 0x00}}, + {2, [3]byte{0xc3, 0x84, 0x00}}, {2, [3]byte{0xc3, 0x85, 0x00}}, + {2, [3]byte{0xc3, 0x86, 0x00}}, {2, [3]byte{0xc3, 0x87, 0x00}}, + {2, [3]byte{0xc3, 0x88, 0x00}}, {2, [3]byte{0xc3, 0x89, 0x00}}, + {2, [3]byte{0xc3, 0x8a, 0x00}}, {2, [3]byte{0xc3, 0x8b, 0x00}}, + {2, [3]byte{0xc3, 0x8c, 0x00}}, {2, [3]byte{0xc3, 0x8d, 0x00}}, + {2, [3]byte{0xc3, 0x8e, 0x00}}, {2, [3]byte{0xc3, 0x8f, 0x00}}, + {2, [3]byte{0xc4, 0x9e, 0x00}}, {2, [3]byte{0xc3, 0x91, 0x00}}, + {2, [3]byte{0xc3, 0x92, 0x00}}, {2, [3]byte{0xc3, 0x93, 0x00}}, + {2, [3]byte{0xc3, 0x94, 0x00}}, {2, [3]byte{0xc3, 0x95, 0x00}}, + {2, [3]byte{0xc3, 0x96, 0x00}}, {2, [3]byte{0xc3, 0x97, 0x00}}, + {2, [3]byte{0xc3, 0x98, 0x00}}, {2, [3]byte{0xc3, 0x99, 0x00}}, + {2, [3]byte{0xc3, 0x9a, 0x00}}, {2, [3]byte{0xc3, 0x9b, 0x00}}, + {2, [3]byte{0xc3, 0x9c, 0x00}}, {2, [3]byte{0xc4, 0xb0, 0x00}}, + {2, [3]byte{0xc5, 0x9e, 0x00}}, {2, [3]byte{0xc3, 0x9f, 0x00}}, + {2, [3]byte{0xc3, 0xa0, 0x00}}, {2, [3]byte{0xc3, 0xa1, 0x00}}, + {2, [3]byte{0xc3, 0xa2, 0x00}}, {2, [3]byte{0xc3, 0xa3, 0x00}}, + {2, [3]byte{0xc3, 0xa4, 0x00}}, {2, [3]byte{0xc3, 0xa5, 0x00}}, + {2, [3]byte{0xc3, 0xa6, 0x00}}, {2, [3]byte{0xc3, 0xa7, 0x00}}, + {2, [3]byte{0xc3, 0xa8, 0x00}}, {2, [3]byte{0xc3, 0xa9, 0x00}}, + {2, [3]byte{0xc3, 0xaa, 0x00}}, {2, [3]byte{0xc3, 0xab, 0x00}}, + {2, [3]byte{0xc3, 0xac, 0x00}}, {2, [3]byte{0xc3, 0xad, 0x00}}, + {2, [3]byte{0xc3, 0xae, 0x00}}, {2, [3]byte{0xc3, 0xaf, 0x00}}, + {2, [3]byte{0xc4, 0x9f, 0x00}}, {2, [3]byte{0xc3, 0xb1, 0x00}}, + {2, [3]byte{0xc3, 0xb2, 0x00}}, {2, [3]byte{0xc3, 0xb3, 0x00}}, + {2, [3]byte{0xc3, 0xb4, 0x00}}, {2, [3]byte{0xc3, 0xb5, 0x00}}, + {2, [3]byte{0xc3, 0xb6, 0x00}}, {2, [3]byte{0xc3, 0xb7, 0x00}}, + {2, [3]byte{0xc3, 0xb8, 0x00}}, {2, [3]byte{0xc3, 0xb9, 0x00}}, + {2, [3]byte{0xc3, 0xba, 0x00}}, {2, [3]byte{0xc3, 0xbb, 0x00}}, + {2, [3]byte{0xc3, 0xbc, 0x00}}, {2, [3]byte{0xc4, 0xb1, 0x00}}, + {2, [3]byte{0xc5, 0x9f, 0x00}}, {2, [3]byte{0xc3, 0xbf, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0x80000080, 0x81000081, 0x82000082, 0x83000083, 0x84000084, 0x85000085, 0x86000086, 0x87000087, + 0x88000088, 0x89000089, 0x8a00008a, 0x8b00008b, 0x8c00008c, 0x8d00008d, 0x8e00008e, 0x8f00008f, + 0x90000090, 0x91000091, 0x92000092, 0x93000093, 0x94000094, 0x95000095, 0x96000096, 0x97000097, + 0x98000098, 0x99000099, 0x9a00009a, 0x9b00009b, 0x9c00009c, 0x9d00009d, 0x9e00009e, 0x9f00009f, + 0xa00000a0, 0xa10000a1, 0xa20000a2, 0xa30000a3, 0xa40000a4, 0xa50000a5, 0xa60000a6, 0xa70000a7, + 0xa80000a8, 0xa90000a9, 0xaa0000aa, 0xab0000ab, 0xac0000ac, 0xad0000ad, 0xae0000ae, 0xaf0000af, + 0xb00000b0, 0xb10000b1, 0xb20000b2, 0xb30000b3, 0xb40000b4, 0xb50000b5, 0xb60000b6, 0xb70000b7, + 0xb80000b8, 0xb90000b9, 0xba0000ba, 0xbb0000bb, 0xbc0000bc, 0xbd0000bd, 0xbe0000be, 0xbf0000bf, + 0xc00000c0, 0xc10000c1, 0xc20000c2, 0xc30000c3, 0xc40000c4, 0xc50000c5, 0xc60000c6, 0xc70000c7, + 0xc80000c8, 0xc90000c9, 0xca0000ca, 0xcb0000cb, 0xcc0000cc, 0xcd0000cd, 0xce0000ce, 0xcf0000cf, + 0xd10000d1, 0xd20000d2, 0xd30000d3, 0xd40000d4, 0xd50000d5, 0xd60000d6, 0xd70000d7, 0xd80000d8, + 0xd90000d9, 0xda0000da, 0xdb0000db, 0xdc0000dc, 0xdf0000df, 0xe00000e0, 0xe10000e1, 0xe20000e2, + 0xe30000e3, 0xe40000e4, 0xe50000e5, 0xe60000e6, 0xe70000e7, 0xe80000e8, 0xe90000e9, 0xea0000ea, + 0xeb0000eb, 0xec0000ec, 0xed0000ed, 0xee0000ee, 0xef0000ef, 0xf10000f1, 0xf20000f2, 0xf30000f3, + 0xf40000f4, 0xf50000f5, 0xf60000f6, 0xf70000f7, 0xf80000f8, 0xf90000f9, 0xfa0000fa, 0xfb0000fb, + 0xfc0000fc, 0xff0000ff, 0xd000011e, 0xf000011f, 0xdd000130, 0xfd000131, 0xde00015e, 0xfe00015f, + }, +} + +// ISO8859_10 is the ISO 8859-10 encoding. +var ISO8859_10 *Charmap = &iso8859_10 + +var iso8859_10 = Charmap{ + name: "ISO 8859-10", + mib: identifier.ISOLatin6, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {2, [3]byte{0xc2, 0xa0, 0x00}}, {2, [3]byte{0xc4, 0x84, 0x00}}, + {2, [3]byte{0xc4, 0x92, 0x00}}, {2, [3]byte{0xc4, 0xa2, 0x00}}, + {2, [3]byte{0xc4, 0xaa, 0x00}}, {2, [3]byte{0xc4, 0xa8, 0x00}}, + {2, [3]byte{0xc4, 0xb6, 0x00}}, {2, [3]byte{0xc2, 0xa7, 0x00}}, + {2, [3]byte{0xc4, 0xbb, 0x00}}, {2, [3]byte{0xc4, 0x90, 0x00}}, + {2, [3]byte{0xc5, 0xa0, 0x00}}, {2, [3]byte{0xc5, 0xa6, 0x00}}, + {2, [3]byte{0xc5, 0xbd, 0x00}}, {2, [3]byte{0xc2, 0xad, 0x00}}, + {2, [3]byte{0xc5, 0xaa, 0x00}}, {2, [3]byte{0xc5, 0x8a, 0x00}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {2, [3]byte{0xc4, 0x85, 0x00}}, + {2, [3]byte{0xc4, 0x93, 0x00}}, {2, [3]byte{0xc4, 0xa3, 0x00}}, + {2, [3]byte{0xc4, 0xab, 0x00}}, {2, [3]byte{0xc4, 0xa9, 0x00}}, + {2, [3]byte{0xc4, 0xb7, 0x00}}, {2, [3]byte{0xc2, 0xb7, 0x00}}, + {2, [3]byte{0xc4, 0xbc, 0x00}}, {2, [3]byte{0xc4, 0x91, 0x00}}, + {2, [3]byte{0xc5, 0xa1, 0x00}}, {2, [3]byte{0xc5, 0xa7, 0x00}}, + {2, [3]byte{0xc5, 0xbe, 0x00}}, {3, [3]byte{0xe2, 0x80, 0x95}}, + {2, [3]byte{0xc5, 0xab, 0x00}}, {2, [3]byte{0xc5, 0x8b, 0x00}}, + {2, [3]byte{0xc4, 0x80, 0x00}}, {2, [3]byte{0xc3, 0x81, 0x00}}, + {2, [3]byte{0xc3, 0x82, 0x00}}, {2, [3]byte{0xc3, 0x83, 0x00}}, + {2, [3]byte{0xc3, 0x84, 0x00}}, {2, [3]byte{0xc3, 0x85, 0x00}}, + {2, [3]byte{0xc3, 0x86, 0x00}}, {2, [3]byte{0xc4, 0xae, 0x00}}, + {2, [3]byte{0xc4, 0x8c, 0x00}}, {2, [3]byte{0xc3, 0x89, 0x00}}, + {2, [3]byte{0xc4, 0x98, 0x00}}, {2, [3]byte{0xc3, 0x8b, 0x00}}, + {2, [3]byte{0xc4, 0x96, 0x00}}, {2, [3]byte{0xc3, 0x8d, 0x00}}, + {2, [3]byte{0xc3, 0x8e, 0x00}}, {2, [3]byte{0xc3, 0x8f, 0x00}}, + {2, [3]byte{0xc3, 0x90, 0x00}}, {2, [3]byte{0xc5, 0x85, 0x00}}, + {2, [3]byte{0xc5, 0x8c, 0x00}}, {2, [3]byte{0xc3, 0x93, 0x00}}, + {2, [3]byte{0xc3, 0x94, 0x00}}, {2, [3]byte{0xc3, 0x95, 0x00}}, + {2, [3]byte{0xc3, 0x96, 0x00}}, {2, [3]byte{0xc5, 0xa8, 0x00}}, + {2, [3]byte{0xc3, 0x98, 0x00}}, {2, [3]byte{0xc5, 0xb2, 0x00}}, + {2, [3]byte{0xc3, 0x9a, 0x00}}, {2, [3]byte{0xc3, 0x9b, 0x00}}, + {2, [3]byte{0xc3, 0x9c, 0x00}}, {2, [3]byte{0xc3, 0x9d, 0x00}}, + {2, [3]byte{0xc3, 0x9e, 0x00}}, {2, [3]byte{0xc3, 0x9f, 0x00}}, + {2, [3]byte{0xc4, 0x81, 0x00}}, {2, [3]byte{0xc3, 0xa1, 0x00}}, + {2, [3]byte{0xc3, 0xa2, 0x00}}, {2, [3]byte{0xc3, 0xa3, 0x00}}, + {2, [3]byte{0xc3, 0xa4, 0x00}}, {2, [3]byte{0xc3, 0xa5, 0x00}}, + {2, [3]byte{0xc3, 0xa6, 0x00}}, {2, [3]byte{0xc4, 0xaf, 0x00}}, + {2, [3]byte{0xc4, 0x8d, 0x00}}, {2, [3]byte{0xc3, 0xa9, 0x00}}, + {2, [3]byte{0xc4, 0x99, 0x00}}, {2, [3]byte{0xc3, 0xab, 0x00}}, + {2, [3]byte{0xc4, 0x97, 0x00}}, {2, [3]byte{0xc3, 0xad, 0x00}}, + {2, [3]byte{0xc3, 0xae, 0x00}}, {2, [3]byte{0xc3, 0xaf, 0x00}}, + {2, [3]byte{0xc3, 0xb0, 0x00}}, {2, [3]byte{0xc5, 0x86, 0x00}}, + {2, [3]byte{0xc5, 0x8d, 0x00}}, {2, [3]byte{0xc3, 0xb3, 0x00}}, + {2, [3]byte{0xc3, 0xb4, 0x00}}, {2, [3]byte{0xc3, 0xb5, 0x00}}, + {2, [3]byte{0xc3, 0xb6, 0x00}}, {2, [3]byte{0xc5, 0xa9, 0x00}}, + {2, [3]byte{0xc3, 0xb8, 0x00}}, {2, [3]byte{0xc5, 0xb3, 0x00}}, + {2, [3]byte{0xc3, 0xba, 0x00}}, {2, [3]byte{0xc3, 0xbb, 0x00}}, + {2, [3]byte{0xc3, 0xbc, 0x00}}, {2, [3]byte{0xc3, 0xbd, 0x00}}, + {2, [3]byte{0xc3, 0xbe, 0x00}}, {2, [3]byte{0xc4, 0xb8, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xa00000a0, 0xa70000a7, 0xad0000ad, 0xb00000b0, 0xb70000b7, 0xc10000c1, 0xc20000c2, 0xc30000c3, + 0xc40000c4, 0xc50000c5, 0xc60000c6, 0xc90000c9, 0xcb0000cb, 0xcd0000cd, 0xce0000ce, 0xcf0000cf, + 0xd00000d0, 0xd30000d3, 0xd40000d4, 0xd50000d5, 0xd60000d6, 0xd80000d8, 0xda0000da, 0xdb0000db, + 0xdc0000dc, 0xdd0000dd, 0xde0000de, 0xdf0000df, 0xe10000e1, 0xe20000e2, 0xe30000e3, 0xe40000e4, + 0xe50000e5, 0xe60000e6, 0xe90000e9, 0xeb0000eb, 0xed0000ed, 0xee0000ee, 0xef0000ef, 0xf00000f0, + 0xf30000f3, 0xf40000f4, 0xf50000f5, 0xf60000f6, 0xf80000f8, 0xfa0000fa, 0xfb0000fb, 0xfc0000fc, + 0xfd0000fd, 0xfe0000fe, 0xc0000100, 0xe0000101, 0xa1000104, 0xb1000105, 0xc800010c, 0xe800010d, + 0xa9000110, 0xb9000111, 0xa2000112, 0xb2000113, 0xcc000116, 0xec000117, 0xca000118, 0xea000119, + 0xa3000122, 0xb3000123, 0xa5000128, 0xb5000129, 0xa400012a, 0xb400012b, 0xc700012e, 0xe700012f, + 0xa6000136, 0xb6000137, 0xff000138, 0xa800013b, 0xb800013c, 0xd1000145, 0xf1000146, 0xaf00014a, + 0xbf00014b, 0xd200014c, 0xf200014d, 0xaa000160, 0xba000161, 0xab000166, 0xbb000167, 0xd7000168, + 0xf7000169, 0xae00016a, 0xbe00016b, 0xd9000172, 0xf9000173, 0xac00017d, 0xbc00017e, 0xbd002015, + 0xbd002015, 0xbd002015, 0xbd002015, 0xbd002015, 0xbd002015, 0xbd002015, 0xbd002015, 0xbd002015, + 0xbd002015, 0xbd002015, 0xbd002015, 0xbd002015, 0xbd002015, 0xbd002015, 0xbd002015, 0xbd002015, + 0xbd002015, 0xbd002015, 0xbd002015, 0xbd002015, 0xbd002015, 0xbd002015, 0xbd002015, 0xbd002015, + 0xbd002015, 0xbd002015, 0xbd002015, 0xbd002015, 0xbd002015, 0xbd002015, 0xbd002015, 0xbd002015, + }, +} + +// ISO8859_13 is the ISO 8859-13 encoding. +var ISO8859_13 *Charmap = &iso8859_13 + +var iso8859_13 = Charmap{ + name: "ISO 8859-13", + mib: identifier.ISO885913, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {2, [3]byte{0xc2, 0xa0, 0x00}}, {3, [3]byte{0xe2, 0x80, 0x9d}}, + {2, [3]byte{0xc2, 0xa2, 0x00}}, {2, [3]byte{0xc2, 0xa3, 0x00}}, + {2, [3]byte{0xc2, 0xa4, 0x00}}, {3, [3]byte{0xe2, 0x80, 0x9e}}, + {2, [3]byte{0xc2, 0xa6, 0x00}}, {2, [3]byte{0xc2, 0xa7, 0x00}}, + {2, [3]byte{0xc3, 0x98, 0x00}}, {2, [3]byte{0xc2, 0xa9, 0x00}}, + {2, [3]byte{0xc5, 0x96, 0x00}}, {2, [3]byte{0xc2, 0xab, 0x00}}, + {2, [3]byte{0xc2, 0xac, 0x00}}, {2, [3]byte{0xc2, 0xad, 0x00}}, + {2, [3]byte{0xc2, 0xae, 0x00}}, {2, [3]byte{0xc3, 0x86, 0x00}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {2, [3]byte{0xc2, 0xb1, 0x00}}, + {2, [3]byte{0xc2, 0xb2, 0x00}}, {2, [3]byte{0xc2, 0xb3, 0x00}}, + {3, [3]byte{0xe2, 0x80, 0x9c}}, {2, [3]byte{0xc2, 0xb5, 0x00}}, + {2, [3]byte{0xc2, 0xb6, 0x00}}, {2, [3]byte{0xc2, 0xb7, 0x00}}, + {2, [3]byte{0xc3, 0xb8, 0x00}}, {2, [3]byte{0xc2, 0xb9, 0x00}}, + {2, [3]byte{0xc5, 0x97, 0x00}}, {2, [3]byte{0xc2, 0xbb, 0x00}}, + {2, [3]byte{0xc2, 0xbc, 0x00}}, {2, [3]byte{0xc2, 0xbd, 0x00}}, + {2, [3]byte{0xc2, 0xbe, 0x00}}, {2, [3]byte{0xc3, 0xa6, 0x00}}, + {2, [3]byte{0xc4, 0x84, 0x00}}, {2, [3]byte{0xc4, 0xae, 0x00}}, + {2, [3]byte{0xc4, 0x80, 0x00}}, {2, [3]byte{0xc4, 0x86, 0x00}}, + {2, [3]byte{0xc3, 0x84, 0x00}}, {2, [3]byte{0xc3, 0x85, 0x00}}, + {2, [3]byte{0xc4, 0x98, 0x00}}, {2, [3]byte{0xc4, 0x92, 0x00}}, + {2, [3]byte{0xc4, 0x8c, 0x00}}, {2, [3]byte{0xc3, 0x89, 0x00}}, + {2, [3]byte{0xc5, 0xb9, 0x00}}, {2, [3]byte{0xc4, 0x96, 0x00}}, + {2, [3]byte{0xc4, 0xa2, 0x00}}, {2, [3]byte{0xc4, 0xb6, 0x00}}, + {2, [3]byte{0xc4, 0xaa, 0x00}}, {2, [3]byte{0xc4, 0xbb, 0x00}}, + {2, [3]byte{0xc5, 0xa0, 0x00}}, {2, [3]byte{0xc5, 0x83, 0x00}}, + {2, [3]byte{0xc5, 0x85, 0x00}}, {2, [3]byte{0xc3, 0x93, 0x00}}, + {2, [3]byte{0xc5, 0x8c, 0x00}}, {2, [3]byte{0xc3, 0x95, 0x00}}, + {2, [3]byte{0xc3, 0x96, 0x00}}, {2, [3]byte{0xc3, 0x97, 0x00}}, + {2, [3]byte{0xc5, 0xb2, 0x00}}, {2, [3]byte{0xc5, 0x81, 0x00}}, + {2, [3]byte{0xc5, 0x9a, 0x00}}, {2, [3]byte{0xc5, 0xaa, 0x00}}, + {2, [3]byte{0xc3, 0x9c, 0x00}}, {2, [3]byte{0xc5, 0xbb, 0x00}}, + {2, [3]byte{0xc5, 0xbd, 0x00}}, {2, [3]byte{0xc3, 0x9f, 0x00}}, + {2, [3]byte{0xc4, 0x85, 0x00}}, {2, [3]byte{0xc4, 0xaf, 0x00}}, + {2, [3]byte{0xc4, 0x81, 0x00}}, {2, [3]byte{0xc4, 0x87, 0x00}}, + {2, [3]byte{0xc3, 0xa4, 0x00}}, {2, [3]byte{0xc3, 0xa5, 0x00}}, + {2, [3]byte{0xc4, 0x99, 0x00}}, {2, [3]byte{0xc4, 0x93, 0x00}}, + {2, [3]byte{0xc4, 0x8d, 0x00}}, {2, [3]byte{0xc3, 0xa9, 0x00}}, + {2, [3]byte{0xc5, 0xba, 0x00}}, {2, [3]byte{0xc4, 0x97, 0x00}}, + {2, [3]byte{0xc4, 0xa3, 0x00}}, {2, [3]byte{0xc4, 0xb7, 0x00}}, + {2, [3]byte{0xc4, 0xab, 0x00}}, {2, [3]byte{0xc4, 0xbc, 0x00}}, + {2, [3]byte{0xc5, 0xa1, 0x00}}, {2, [3]byte{0xc5, 0x84, 0x00}}, + {2, [3]byte{0xc5, 0x86, 0x00}}, {2, [3]byte{0xc3, 0xb3, 0x00}}, + {2, [3]byte{0xc5, 0x8d, 0x00}}, {2, [3]byte{0xc3, 0xb5, 0x00}}, + {2, [3]byte{0xc3, 0xb6, 0x00}}, {2, [3]byte{0xc3, 0xb7, 0x00}}, + {2, [3]byte{0xc5, 0xb3, 0x00}}, {2, [3]byte{0xc5, 0x82, 0x00}}, + {2, [3]byte{0xc5, 0x9b, 0x00}}, {2, [3]byte{0xc5, 0xab, 0x00}}, + {2, [3]byte{0xc3, 0xbc, 0x00}}, {2, [3]byte{0xc5, 0xbc, 0x00}}, + {2, [3]byte{0xc5, 0xbe, 0x00}}, {3, [3]byte{0xe2, 0x80, 0x99}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xa00000a0, 0xa20000a2, 0xa30000a3, 0xa40000a4, 0xa60000a6, 0xa70000a7, 0xa90000a9, 0xab0000ab, + 0xac0000ac, 0xad0000ad, 0xae0000ae, 0xb00000b0, 0xb10000b1, 0xb20000b2, 0xb30000b3, 0xb50000b5, + 0xb60000b6, 0xb70000b7, 0xb90000b9, 0xbb0000bb, 0xbc0000bc, 0xbd0000bd, 0xbe0000be, 0xc40000c4, + 0xc50000c5, 0xaf0000c6, 0xc90000c9, 0xd30000d3, 0xd50000d5, 0xd60000d6, 0xd70000d7, 0xa80000d8, + 0xdc0000dc, 0xdf0000df, 0xe40000e4, 0xe50000e5, 0xbf0000e6, 0xe90000e9, 0xf30000f3, 0xf50000f5, + 0xf60000f6, 0xf70000f7, 0xb80000f8, 0xfc0000fc, 0xc2000100, 0xe2000101, 0xc0000104, 0xe0000105, + 0xc3000106, 0xe3000107, 0xc800010c, 0xe800010d, 0xc7000112, 0xe7000113, 0xcb000116, 0xeb000117, + 0xc6000118, 0xe6000119, 0xcc000122, 0xec000123, 0xce00012a, 0xee00012b, 0xc100012e, 0xe100012f, + 0xcd000136, 0xed000137, 0xcf00013b, 0xef00013c, 0xd9000141, 0xf9000142, 0xd1000143, 0xf1000144, + 0xd2000145, 0xf2000146, 0xd400014c, 0xf400014d, 0xaa000156, 0xba000157, 0xda00015a, 0xfa00015b, + 0xd0000160, 0xf0000161, 0xdb00016a, 0xfb00016b, 0xd8000172, 0xf8000173, 0xca000179, 0xea00017a, + 0xdd00017b, 0xfd00017c, 0xde00017d, 0xfe00017e, 0xff002019, 0xb400201c, 0xa100201d, 0xa500201e, + 0xa500201e, 0xa500201e, 0xa500201e, 0xa500201e, 0xa500201e, 0xa500201e, 0xa500201e, 0xa500201e, + 0xa500201e, 0xa500201e, 0xa500201e, 0xa500201e, 0xa500201e, 0xa500201e, 0xa500201e, 0xa500201e, + 0xa500201e, 0xa500201e, 0xa500201e, 0xa500201e, 0xa500201e, 0xa500201e, 0xa500201e, 0xa500201e, + 0xa500201e, 0xa500201e, 0xa500201e, 0xa500201e, 0xa500201e, 0xa500201e, 0xa500201e, 0xa500201e, + }, +} + +// ISO8859_14 is the ISO 8859-14 encoding. +var ISO8859_14 *Charmap = &iso8859_14 + +var iso8859_14 = Charmap{ + name: "ISO 8859-14", + mib: identifier.ISO885914, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {2, [3]byte{0xc2, 0xa0, 0x00}}, {3, [3]byte{0xe1, 0xb8, 0x82}}, + {3, [3]byte{0xe1, 0xb8, 0x83}}, {2, [3]byte{0xc2, 0xa3, 0x00}}, + {2, [3]byte{0xc4, 0x8a, 0x00}}, {2, [3]byte{0xc4, 0x8b, 0x00}}, + {3, [3]byte{0xe1, 0xb8, 0x8a}}, {2, [3]byte{0xc2, 0xa7, 0x00}}, + {3, [3]byte{0xe1, 0xba, 0x80}}, {2, [3]byte{0xc2, 0xa9, 0x00}}, + {3, [3]byte{0xe1, 0xba, 0x82}}, {3, [3]byte{0xe1, 0xb8, 0x8b}}, + {3, [3]byte{0xe1, 0xbb, 0xb2}}, {2, [3]byte{0xc2, 0xad, 0x00}}, + {2, [3]byte{0xc2, 0xae, 0x00}}, {2, [3]byte{0xc5, 0xb8, 0x00}}, + {3, [3]byte{0xe1, 0xb8, 0x9e}}, {3, [3]byte{0xe1, 0xb8, 0x9f}}, + {2, [3]byte{0xc4, 0xa0, 0x00}}, {2, [3]byte{0xc4, 0xa1, 0x00}}, + {3, [3]byte{0xe1, 0xb9, 0x80}}, {3, [3]byte{0xe1, 0xb9, 0x81}}, + {2, [3]byte{0xc2, 0xb6, 0x00}}, {3, [3]byte{0xe1, 0xb9, 0x96}}, + {3, [3]byte{0xe1, 0xba, 0x81}}, {3, [3]byte{0xe1, 0xb9, 0x97}}, + {3, [3]byte{0xe1, 0xba, 0x83}}, {3, [3]byte{0xe1, 0xb9, 0xa0}}, + {3, [3]byte{0xe1, 0xbb, 0xb3}}, {3, [3]byte{0xe1, 0xba, 0x84}}, + {3, [3]byte{0xe1, 0xba, 0x85}}, {3, [3]byte{0xe1, 0xb9, 0xa1}}, + {2, [3]byte{0xc3, 0x80, 0x00}}, {2, [3]byte{0xc3, 0x81, 0x00}}, + {2, [3]byte{0xc3, 0x82, 0x00}}, {2, [3]byte{0xc3, 0x83, 0x00}}, + {2, [3]byte{0xc3, 0x84, 0x00}}, {2, [3]byte{0xc3, 0x85, 0x00}}, + {2, [3]byte{0xc3, 0x86, 0x00}}, {2, [3]byte{0xc3, 0x87, 0x00}}, + {2, [3]byte{0xc3, 0x88, 0x00}}, {2, [3]byte{0xc3, 0x89, 0x00}}, + {2, [3]byte{0xc3, 0x8a, 0x00}}, {2, [3]byte{0xc3, 0x8b, 0x00}}, + {2, [3]byte{0xc3, 0x8c, 0x00}}, {2, [3]byte{0xc3, 0x8d, 0x00}}, + {2, [3]byte{0xc3, 0x8e, 0x00}}, {2, [3]byte{0xc3, 0x8f, 0x00}}, + {2, [3]byte{0xc5, 0xb4, 0x00}}, {2, [3]byte{0xc3, 0x91, 0x00}}, + {2, [3]byte{0xc3, 0x92, 0x00}}, {2, [3]byte{0xc3, 0x93, 0x00}}, + {2, [3]byte{0xc3, 0x94, 0x00}}, {2, [3]byte{0xc3, 0x95, 0x00}}, + {2, [3]byte{0xc3, 0x96, 0x00}}, {3, [3]byte{0xe1, 0xb9, 0xaa}}, + {2, [3]byte{0xc3, 0x98, 0x00}}, {2, [3]byte{0xc3, 0x99, 0x00}}, + {2, [3]byte{0xc3, 0x9a, 0x00}}, {2, [3]byte{0xc3, 0x9b, 0x00}}, + {2, [3]byte{0xc3, 0x9c, 0x00}}, {2, [3]byte{0xc3, 0x9d, 0x00}}, + {2, [3]byte{0xc5, 0xb6, 0x00}}, {2, [3]byte{0xc3, 0x9f, 0x00}}, + {2, [3]byte{0xc3, 0xa0, 0x00}}, {2, [3]byte{0xc3, 0xa1, 0x00}}, + {2, [3]byte{0xc3, 0xa2, 0x00}}, {2, [3]byte{0xc3, 0xa3, 0x00}}, + {2, [3]byte{0xc3, 0xa4, 0x00}}, {2, [3]byte{0xc3, 0xa5, 0x00}}, + {2, [3]byte{0xc3, 0xa6, 0x00}}, {2, [3]byte{0xc3, 0xa7, 0x00}}, + {2, [3]byte{0xc3, 0xa8, 0x00}}, {2, [3]byte{0xc3, 0xa9, 0x00}}, + {2, [3]byte{0xc3, 0xaa, 0x00}}, {2, [3]byte{0xc3, 0xab, 0x00}}, + {2, [3]byte{0xc3, 0xac, 0x00}}, {2, [3]byte{0xc3, 0xad, 0x00}}, + {2, [3]byte{0xc3, 0xae, 0x00}}, {2, [3]byte{0xc3, 0xaf, 0x00}}, + {2, [3]byte{0xc5, 0xb5, 0x00}}, {2, [3]byte{0xc3, 0xb1, 0x00}}, + {2, [3]byte{0xc3, 0xb2, 0x00}}, {2, [3]byte{0xc3, 0xb3, 0x00}}, + {2, [3]byte{0xc3, 0xb4, 0x00}}, {2, [3]byte{0xc3, 0xb5, 0x00}}, + {2, [3]byte{0xc3, 0xb6, 0x00}}, {3, [3]byte{0xe1, 0xb9, 0xab}}, + {2, [3]byte{0xc3, 0xb8, 0x00}}, {2, [3]byte{0xc3, 0xb9, 0x00}}, + {2, [3]byte{0xc3, 0xba, 0x00}}, {2, [3]byte{0xc3, 0xbb, 0x00}}, + {2, [3]byte{0xc3, 0xbc, 0x00}}, {2, [3]byte{0xc3, 0xbd, 0x00}}, + {2, [3]byte{0xc5, 0xb7, 0x00}}, {2, [3]byte{0xc3, 0xbf, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xa00000a0, 0xa30000a3, 0xa70000a7, 0xa90000a9, 0xad0000ad, 0xae0000ae, 0xb60000b6, 0xc00000c0, + 0xc10000c1, 0xc20000c2, 0xc30000c3, 0xc40000c4, 0xc50000c5, 0xc60000c6, 0xc70000c7, 0xc80000c8, + 0xc90000c9, 0xca0000ca, 0xcb0000cb, 0xcc0000cc, 0xcd0000cd, 0xce0000ce, 0xcf0000cf, 0xd10000d1, + 0xd20000d2, 0xd30000d3, 0xd40000d4, 0xd50000d5, 0xd60000d6, 0xd80000d8, 0xd90000d9, 0xda0000da, + 0xdb0000db, 0xdc0000dc, 0xdd0000dd, 0xdf0000df, 0xe00000e0, 0xe10000e1, 0xe20000e2, 0xe30000e3, + 0xe40000e4, 0xe50000e5, 0xe60000e6, 0xe70000e7, 0xe80000e8, 0xe90000e9, 0xea0000ea, 0xeb0000eb, + 0xec0000ec, 0xed0000ed, 0xee0000ee, 0xef0000ef, 0xf10000f1, 0xf20000f2, 0xf30000f3, 0xf40000f4, + 0xf50000f5, 0xf60000f6, 0xf80000f8, 0xf90000f9, 0xfa0000fa, 0xfb0000fb, 0xfc0000fc, 0xfd0000fd, + 0xff0000ff, 0xa400010a, 0xa500010b, 0xb2000120, 0xb3000121, 0xd0000174, 0xf0000175, 0xde000176, + 0xfe000177, 0xaf000178, 0xa1001e02, 0xa2001e03, 0xa6001e0a, 0xab001e0b, 0xb0001e1e, 0xb1001e1f, + 0xb4001e40, 0xb5001e41, 0xb7001e56, 0xb9001e57, 0xbb001e60, 0xbf001e61, 0xd7001e6a, 0xf7001e6b, + 0xa8001e80, 0xb8001e81, 0xaa001e82, 0xba001e83, 0xbd001e84, 0xbe001e85, 0xac001ef2, 0xbc001ef3, + 0xbc001ef3, 0xbc001ef3, 0xbc001ef3, 0xbc001ef3, 0xbc001ef3, 0xbc001ef3, 0xbc001ef3, 0xbc001ef3, + 0xbc001ef3, 0xbc001ef3, 0xbc001ef3, 0xbc001ef3, 0xbc001ef3, 0xbc001ef3, 0xbc001ef3, 0xbc001ef3, + 0xbc001ef3, 0xbc001ef3, 0xbc001ef3, 0xbc001ef3, 0xbc001ef3, 0xbc001ef3, 0xbc001ef3, 0xbc001ef3, + 0xbc001ef3, 0xbc001ef3, 0xbc001ef3, 0xbc001ef3, 0xbc001ef3, 0xbc001ef3, 0xbc001ef3, 0xbc001ef3, + }, +} + +// ISO8859_15 is the ISO 8859-15 encoding. +var ISO8859_15 *Charmap = &iso8859_15 + +var iso8859_15 = Charmap{ + name: "ISO 8859-15", + mib: identifier.ISO885915, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {2, [3]byte{0xc2, 0xa0, 0x00}}, {2, [3]byte{0xc2, 0xa1, 0x00}}, + {2, [3]byte{0xc2, 0xa2, 0x00}}, {2, [3]byte{0xc2, 0xa3, 0x00}}, + {3, [3]byte{0xe2, 0x82, 0xac}}, {2, [3]byte{0xc2, 0xa5, 0x00}}, + {2, [3]byte{0xc5, 0xa0, 0x00}}, {2, [3]byte{0xc2, 0xa7, 0x00}}, + {2, [3]byte{0xc5, 0xa1, 0x00}}, {2, [3]byte{0xc2, 0xa9, 0x00}}, + {2, [3]byte{0xc2, 0xaa, 0x00}}, {2, [3]byte{0xc2, 0xab, 0x00}}, + {2, [3]byte{0xc2, 0xac, 0x00}}, {2, [3]byte{0xc2, 0xad, 0x00}}, + {2, [3]byte{0xc2, 0xae, 0x00}}, {2, [3]byte{0xc2, 0xaf, 0x00}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {2, [3]byte{0xc2, 0xb1, 0x00}}, + {2, [3]byte{0xc2, 0xb2, 0x00}}, {2, [3]byte{0xc2, 0xb3, 0x00}}, + {2, [3]byte{0xc5, 0xbd, 0x00}}, {2, [3]byte{0xc2, 0xb5, 0x00}}, + {2, [3]byte{0xc2, 0xb6, 0x00}}, {2, [3]byte{0xc2, 0xb7, 0x00}}, + {2, [3]byte{0xc5, 0xbe, 0x00}}, {2, [3]byte{0xc2, 0xb9, 0x00}}, + {2, [3]byte{0xc2, 0xba, 0x00}}, {2, [3]byte{0xc2, 0xbb, 0x00}}, + {2, [3]byte{0xc5, 0x92, 0x00}}, {2, [3]byte{0xc5, 0x93, 0x00}}, + {2, [3]byte{0xc5, 0xb8, 0x00}}, {2, [3]byte{0xc2, 0xbf, 0x00}}, + {2, [3]byte{0xc3, 0x80, 0x00}}, {2, [3]byte{0xc3, 0x81, 0x00}}, + {2, [3]byte{0xc3, 0x82, 0x00}}, {2, [3]byte{0xc3, 0x83, 0x00}}, + {2, [3]byte{0xc3, 0x84, 0x00}}, {2, [3]byte{0xc3, 0x85, 0x00}}, + {2, [3]byte{0xc3, 0x86, 0x00}}, {2, [3]byte{0xc3, 0x87, 0x00}}, + {2, [3]byte{0xc3, 0x88, 0x00}}, {2, [3]byte{0xc3, 0x89, 0x00}}, + {2, [3]byte{0xc3, 0x8a, 0x00}}, {2, [3]byte{0xc3, 0x8b, 0x00}}, + {2, [3]byte{0xc3, 0x8c, 0x00}}, {2, [3]byte{0xc3, 0x8d, 0x00}}, + {2, [3]byte{0xc3, 0x8e, 0x00}}, {2, [3]byte{0xc3, 0x8f, 0x00}}, + {2, [3]byte{0xc3, 0x90, 0x00}}, {2, [3]byte{0xc3, 0x91, 0x00}}, + {2, [3]byte{0xc3, 0x92, 0x00}}, {2, [3]byte{0xc3, 0x93, 0x00}}, + {2, [3]byte{0xc3, 0x94, 0x00}}, {2, [3]byte{0xc3, 0x95, 0x00}}, + {2, [3]byte{0xc3, 0x96, 0x00}}, {2, [3]byte{0xc3, 0x97, 0x00}}, + {2, [3]byte{0xc3, 0x98, 0x00}}, {2, [3]byte{0xc3, 0x99, 0x00}}, + {2, [3]byte{0xc3, 0x9a, 0x00}}, {2, [3]byte{0xc3, 0x9b, 0x00}}, + {2, [3]byte{0xc3, 0x9c, 0x00}}, {2, [3]byte{0xc3, 0x9d, 0x00}}, + {2, [3]byte{0xc3, 0x9e, 0x00}}, {2, [3]byte{0xc3, 0x9f, 0x00}}, + {2, [3]byte{0xc3, 0xa0, 0x00}}, {2, [3]byte{0xc3, 0xa1, 0x00}}, + {2, [3]byte{0xc3, 0xa2, 0x00}}, {2, [3]byte{0xc3, 0xa3, 0x00}}, + {2, [3]byte{0xc3, 0xa4, 0x00}}, {2, [3]byte{0xc3, 0xa5, 0x00}}, + {2, [3]byte{0xc3, 0xa6, 0x00}}, {2, [3]byte{0xc3, 0xa7, 0x00}}, + {2, [3]byte{0xc3, 0xa8, 0x00}}, {2, [3]byte{0xc3, 0xa9, 0x00}}, + {2, [3]byte{0xc3, 0xaa, 0x00}}, {2, [3]byte{0xc3, 0xab, 0x00}}, + {2, [3]byte{0xc3, 0xac, 0x00}}, {2, [3]byte{0xc3, 0xad, 0x00}}, + {2, [3]byte{0xc3, 0xae, 0x00}}, {2, [3]byte{0xc3, 0xaf, 0x00}}, + {2, [3]byte{0xc3, 0xb0, 0x00}}, {2, [3]byte{0xc3, 0xb1, 0x00}}, + {2, [3]byte{0xc3, 0xb2, 0x00}}, {2, [3]byte{0xc3, 0xb3, 0x00}}, + {2, [3]byte{0xc3, 0xb4, 0x00}}, {2, [3]byte{0xc3, 0xb5, 0x00}}, + {2, [3]byte{0xc3, 0xb6, 0x00}}, {2, [3]byte{0xc3, 0xb7, 0x00}}, + {2, [3]byte{0xc3, 0xb8, 0x00}}, {2, [3]byte{0xc3, 0xb9, 0x00}}, + {2, [3]byte{0xc3, 0xba, 0x00}}, {2, [3]byte{0xc3, 0xbb, 0x00}}, + {2, [3]byte{0xc3, 0xbc, 0x00}}, {2, [3]byte{0xc3, 0xbd, 0x00}}, + {2, [3]byte{0xc3, 0xbe, 0x00}}, {2, [3]byte{0xc3, 0xbf, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xa00000a0, 0xa10000a1, 0xa20000a2, 0xa30000a3, 0xa50000a5, 0xa70000a7, 0xa90000a9, 0xaa0000aa, + 0xab0000ab, 0xac0000ac, 0xad0000ad, 0xae0000ae, 0xaf0000af, 0xb00000b0, 0xb10000b1, 0xb20000b2, + 0xb30000b3, 0xb50000b5, 0xb60000b6, 0xb70000b7, 0xb90000b9, 0xba0000ba, 0xbb0000bb, 0xbf0000bf, + 0xc00000c0, 0xc10000c1, 0xc20000c2, 0xc30000c3, 0xc40000c4, 0xc50000c5, 0xc60000c6, 0xc70000c7, + 0xc80000c8, 0xc90000c9, 0xca0000ca, 0xcb0000cb, 0xcc0000cc, 0xcd0000cd, 0xce0000ce, 0xcf0000cf, + 0xd00000d0, 0xd10000d1, 0xd20000d2, 0xd30000d3, 0xd40000d4, 0xd50000d5, 0xd60000d6, 0xd70000d7, + 0xd80000d8, 0xd90000d9, 0xda0000da, 0xdb0000db, 0xdc0000dc, 0xdd0000dd, 0xde0000de, 0xdf0000df, + 0xe00000e0, 0xe10000e1, 0xe20000e2, 0xe30000e3, 0xe40000e4, 0xe50000e5, 0xe60000e6, 0xe70000e7, + 0xe80000e8, 0xe90000e9, 0xea0000ea, 0xeb0000eb, 0xec0000ec, 0xed0000ed, 0xee0000ee, 0xef0000ef, + 0xf00000f0, 0xf10000f1, 0xf20000f2, 0xf30000f3, 0xf40000f4, 0xf50000f5, 0xf60000f6, 0xf70000f7, + 0xf80000f8, 0xf90000f9, 0xfa0000fa, 0xfb0000fb, 0xfc0000fc, 0xfd0000fd, 0xfe0000fe, 0xff0000ff, + 0xbc000152, 0xbd000153, 0xa6000160, 0xa8000161, 0xbe000178, 0xb400017d, 0xb800017e, 0xa40020ac, + 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, + 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, + 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, + 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, + }, +} + +// ISO8859_16 is the ISO 8859-16 encoding. +var ISO8859_16 *Charmap = &iso8859_16 + +var iso8859_16 = Charmap{ + name: "ISO 8859-16", + mib: identifier.ISO885916, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {2, [3]byte{0xc2, 0xa0, 0x00}}, {2, [3]byte{0xc4, 0x84, 0x00}}, + {2, [3]byte{0xc4, 0x85, 0x00}}, {2, [3]byte{0xc5, 0x81, 0x00}}, + {3, [3]byte{0xe2, 0x82, 0xac}}, {3, [3]byte{0xe2, 0x80, 0x9e}}, + {2, [3]byte{0xc5, 0xa0, 0x00}}, {2, [3]byte{0xc2, 0xa7, 0x00}}, + {2, [3]byte{0xc5, 0xa1, 0x00}}, {2, [3]byte{0xc2, 0xa9, 0x00}}, + {2, [3]byte{0xc8, 0x98, 0x00}}, {2, [3]byte{0xc2, 0xab, 0x00}}, + {2, [3]byte{0xc5, 0xb9, 0x00}}, {2, [3]byte{0xc2, 0xad, 0x00}}, + {2, [3]byte{0xc5, 0xba, 0x00}}, {2, [3]byte{0xc5, 0xbb, 0x00}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {2, [3]byte{0xc2, 0xb1, 0x00}}, + {2, [3]byte{0xc4, 0x8c, 0x00}}, {2, [3]byte{0xc5, 0x82, 0x00}}, + {2, [3]byte{0xc5, 0xbd, 0x00}}, {3, [3]byte{0xe2, 0x80, 0x9d}}, + {2, [3]byte{0xc2, 0xb6, 0x00}}, {2, [3]byte{0xc2, 0xb7, 0x00}}, + {2, [3]byte{0xc5, 0xbe, 0x00}}, {2, [3]byte{0xc4, 0x8d, 0x00}}, + {2, [3]byte{0xc8, 0x99, 0x00}}, {2, [3]byte{0xc2, 0xbb, 0x00}}, + {2, [3]byte{0xc5, 0x92, 0x00}}, {2, [3]byte{0xc5, 0x93, 0x00}}, + {2, [3]byte{0xc5, 0xb8, 0x00}}, {2, [3]byte{0xc5, 0xbc, 0x00}}, + {2, [3]byte{0xc3, 0x80, 0x00}}, {2, [3]byte{0xc3, 0x81, 0x00}}, + {2, [3]byte{0xc3, 0x82, 0x00}}, {2, [3]byte{0xc4, 0x82, 0x00}}, + {2, [3]byte{0xc3, 0x84, 0x00}}, {2, [3]byte{0xc4, 0x86, 0x00}}, + {2, [3]byte{0xc3, 0x86, 0x00}}, {2, [3]byte{0xc3, 0x87, 0x00}}, + {2, [3]byte{0xc3, 0x88, 0x00}}, {2, [3]byte{0xc3, 0x89, 0x00}}, + {2, [3]byte{0xc3, 0x8a, 0x00}}, {2, [3]byte{0xc3, 0x8b, 0x00}}, + {2, [3]byte{0xc3, 0x8c, 0x00}}, {2, [3]byte{0xc3, 0x8d, 0x00}}, + {2, [3]byte{0xc3, 0x8e, 0x00}}, {2, [3]byte{0xc3, 0x8f, 0x00}}, + {2, [3]byte{0xc4, 0x90, 0x00}}, {2, [3]byte{0xc5, 0x83, 0x00}}, + {2, [3]byte{0xc3, 0x92, 0x00}}, {2, [3]byte{0xc3, 0x93, 0x00}}, + {2, [3]byte{0xc3, 0x94, 0x00}}, {2, [3]byte{0xc5, 0x90, 0x00}}, + {2, [3]byte{0xc3, 0x96, 0x00}}, {2, [3]byte{0xc5, 0x9a, 0x00}}, + {2, [3]byte{0xc5, 0xb0, 0x00}}, {2, [3]byte{0xc3, 0x99, 0x00}}, + {2, [3]byte{0xc3, 0x9a, 0x00}}, {2, [3]byte{0xc3, 0x9b, 0x00}}, + {2, [3]byte{0xc3, 0x9c, 0x00}}, {2, [3]byte{0xc4, 0x98, 0x00}}, + {2, [3]byte{0xc8, 0x9a, 0x00}}, {2, [3]byte{0xc3, 0x9f, 0x00}}, + {2, [3]byte{0xc3, 0xa0, 0x00}}, {2, [3]byte{0xc3, 0xa1, 0x00}}, + {2, [3]byte{0xc3, 0xa2, 0x00}}, {2, [3]byte{0xc4, 0x83, 0x00}}, + {2, [3]byte{0xc3, 0xa4, 0x00}}, {2, [3]byte{0xc4, 0x87, 0x00}}, + {2, [3]byte{0xc3, 0xa6, 0x00}}, {2, [3]byte{0xc3, 0xa7, 0x00}}, + {2, [3]byte{0xc3, 0xa8, 0x00}}, {2, [3]byte{0xc3, 0xa9, 0x00}}, + {2, [3]byte{0xc3, 0xaa, 0x00}}, {2, [3]byte{0xc3, 0xab, 0x00}}, + {2, [3]byte{0xc3, 0xac, 0x00}}, {2, [3]byte{0xc3, 0xad, 0x00}}, + {2, [3]byte{0xc3, 0xae, 0x00}}, {2, [3]byte{0xc3, 0xaf, 0x00}}, + {2, [3]byte{0xc4, 0x91, 0x00}}, {2, [3]byte{0xc5, 0x84, 0x00}}, + {2, [3]byte{0xc3, 0xb2, 0x00}}, {2, [3]byte{0xc3, 0xb3, 0x00}}, + {2, [3]byte{0xc3, 0xb4, 0x00}}, {2, [3]byte{0xc5, 0x91, 0x00}}, + {2, [3]byte{0xc3, 0xb6, 0x00}}, {2, [3]byte{0xc5, 0x9b, 0x00}}, + {2, [3]byte{0xc5, 0xb1, 0x00}}, {2, [3]byte{0xc3, 0xb9, 0x00}}, + {2, [3]byte{0xc3, 0xba, 0x00}}, {2, [3]byte{0xc3, 0xbb, 0x00}}, + {2, [3]byte{0xc3, 0xbc, 0x00}}, {2, [3]byte{0xc4, 0x99, 0x00}}, + {2, [3]byte{0xc8, 0x9b, 0x00}}, {2, [3]byte{0xc3, 0xbf, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xa00000a0, 0xa70000a7, 0xa90000a9, 0xab0000ab, 0xad0000ad, 0xb00000b0, 0xb10000b1, 0xb60000b6, + 0xb70000b7, 0xbb0000bb, 0xc00000c0, 0xc10000c1, 0xc20000c2, 0xc40000c4, 0xc60000c6, 0xc70000c7, + 0xc80000c8, 0xc90000c9, 0xca0000ca, 0xcb0000cb, 0xcc0000cc, 0xcd0000cd, 0xce0000ce, 0xcf0000cf, + 0xd20000d2, 0xd30000d3, 0xd40000d4, 0xd60000d6, 0xd90000d9, 0xda0000da, 0xdb0000db, 0xdc0000dc, + 0xdf0000df, 0xe00000e0, 0xe10000e1, 0xe20000e2, 0xe40000e4, 0xe60000e6, 0xe70000e7, 0xe80000e8, + 0xe90000e9, 0xea0000ea, 0xeb0000eb, 0xec0000ec, 0xed0000ed, 0xee0000ee, 0xef0000ef, 0xf20000f2, + 0xf30000f3, 0xf40000f4, 0xf60000f6, 0xf90000f9, 0xfa0000fa, 0xfb0000fb, 0xfc0000fc, 0xff0000ff, + 0xc3000102, 0xe3000103, 0xa1000104, 0xa2000105, 0xc5000106, 0xe5000107, 0xb200010c, 0xb900010d, + 0xd0000110, 0xf0000111, 0xdd000118, 0xfd000119, 0xa3000141, 0xb3000142, 0xd1000143, 0xf1000144, + 0xd5000150, 0xf5000151, 0xbc000152, 0xbd000153, 0xd700015a, 0xf700015b, 0xa6000160, 0xa8000161, + 0xd8000170, 0xf8000171, 0xbe000178, 0xac000179, 0xae00017a, 0xaf00017b, 0xbf00017c, 0xb400017d, + 0xb800017e, 0xaa000218, 0xba000219, 0xde00021a, 0xfe00021b, 0xb500201d, 0xa500201e, 0xa40020ac, + 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, + 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, + 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, + 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, 0xa40020ac, + }, +} + +// KOI8R is the KOI8-R encoding. +var KOI8R *Charmap = &koi8R + +var koi8R = Charmap{ + name: "KOI8-R", + mib: identifier.KOI8R, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {3, [3]byte{0xe2, 0x94, 0x80}}, {3, [3]byte{0xe2, 0x94, 0x82}}, + {3, [3]byte{0xe2, 0x94, 0x8c}}, {3, [3]byte{0xe2, 0x94, 0x90}}, + {3, [3]byte{0xe2, 0x94, 0x94}}, {3, [3]byte{0xe2, 0x94, 0x98}}, + {3, [3]byte{0xe2, 0x94, 0x9c}}, {3, [3]byte{0xe2, 0x94, 0xa4}}, + {3, [3]byte{0xe2, 0x94, 0xac}}, {3, [3]byte{0xe2, 0x94, 0xb4}}, + {3, [3]byte{0xe2, 0x94, 0xbc}}, {3, [3]byte{0xe2, 0x96, 0x80}}, + {3, [3]byte{0xe2, 0x96, 0x84}}, {3, [3]byte{0xe2, 0x96, 0x88}}, + {3, [3]byte{0xe2, 0x96, 0x8c}}, {3, [3]byte{0xe2, 0x96, 0x90}}, + {3, [3]byte{0xe2, 0x96, 0x91}}, {3, [3]byte{0xe2, 0x96, 0x92}}, + {3, [3]byte{0xe2, 0x96, 0x93}}, {3, [3]byte{0xe2, 0x8c, 0xa0}}, + {3, [3]byte{0xe2, 0x96, 0xa0}}, {3, [3]byte{0xe2, 0x88, 0x99}}, + {3, [3]byte{0xe2, 0x88, 0x9a}}, {3, [3]byte{0xe2, 0x89, 0x88}}, + {3, [3]byte{0xe2, 0x89, 0xa4}}, {3, [3]byte{0xe2, 0x89, 0xa5}}, + {2, [3]byte{0xc2, 0xa0, 0x00}}, {3, [3]byte{0xe2, 0x8c, 0xa1}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {2, [3]byte{0xc2, 0xb2, 0x00}}, + {2, [3]byte{0xc2, 0xb7, 0x00}}, {2, [3]byte{0xc3, 0xb7, 0x00}}, + {3, [3]byte{0xe2, 0x95, 0x90}}, {3, [3]byte{0xe2, 0x95, 0x91}}, + {3, [3]byte{0xe2, 0x95, 0x92}}, {2, [3]byte{0xd1, 0x91, 0x00}}, + {3, [3]byte{0xe2, 0x95, 0x93}}, {3, [3]byte{0xe2, 0x95, 0x94}}, + {3, [3]byte{0xe2, 0x95, 0x95}}, {3, [3]byte{0xe2, 0x95, 0x96}}, + {3, [3]byte{0xe2, 0x95, 0x97}}, {3, [3]byte{0xe2, 0x95, 0x98}}, + {3, [3]byte{0xe2, 0x95, 0x99}}, {3, [3]byte{0xe2, 0x95, 0x9a}}, + {3, [3]byte{0xe2, 0x95, 0x9b}}, {3, [3]byte{0xe2, 0x95, 0x9c}}, + {3, [3]byte{0xe2, 0x95, 0x9d}}, {3, [3]byte{0xe2, 0x95, 0x9e}}, + {3, [3]byte{0xe2, 0x95, 0x9f}}, {3, [3]byte{0xe2, 0x95, 0xa0}}, + {3, [3]byte{0xe2, 0x95, 0xa1}}, {2, [3]byte{0xd0, 0x81, 0x00}}, + {3, [3]byte{0xe2, 0x95, 0xa2}}, {3, [3]byte{0xe2, 0x95, 0xa3}}, + {3, [3]byte{0xe2, 0x95, 0xa4}}, {3, [3]byte{0xe2, 0x95, 0xa5}}, + {3, [3]byte{0xe2, 0x95, 0xa6}}, {3, [3]byte{0xe2, 0x95, 0xa7}}, + {3, [3]byte{0xe2, 0x95, 0xa8}}, {3, [3]byte{0xe2, 0x95, 0xa9}}, + {3, [3]byte{0xe2, 0x95, 0xaa}}, {3, [3]byte{0xe2, 0x95, 0xab}}, + {3, [3]byte{0xe2, 0x95, 0xac}}, {2, [3]byte{0xc2, 0xa9, 0x00}}, + {2, [3]byte{0xd1, 0x8e, 0x00}}, {2, [3]byte{0xd0, 0xb0, 0x00}}, + {2, [3]byte{0xd0, 0xb1, 0x00}}, {2, [3]byte{0xd1, 0x86, 0x00}}, + {2, [3]byte{0xd0, 0xb4, 0x00}}, {2, [3]byte{0xd0, 0xb5, 0x00}}, + {2, [3]byte{0xd1, 0x84, 0x00}}, {2, [3]byte{0xd0, 0xb3, 0x00}}, + {2, [3]byte{0xd1, 0x85, 0x00}}, {2, [3]byte{0xd0, 0xb8, 0x00}}, + {2, [3]byte{0xd0, 0xb9, 0x00}}, {2, [3]byte{0xd0, 0xba, 0x00}}, + {2, [3]byte{0xd0, 0xbb, 0x00}}, {2, [3]byte{0xd0, 0xbc, 0x00}}, + {2, [3]byte{0xd0, 0xbd, 0x00}}, {2, [3]byte{0xd0, 0xbe, 0x00}}, + {2, [3]byte{0xd0, 0xbf, 0x00}}, {2, [3]byte{0xd1, 0x8f, 0x00}}, + {2, [3]byte{0xd1, 0x80, 0x00}}, {2, [3]byte{0xd1, 0x81, 0x00}}, + {2, [3]byte{0xd1, 0x82, 0x00}}, {2, [3]byte{0xd1, 0x83, 0x00}}, + {2, [3]byte{0xd0, 0xb6, 0x00}}, {2, [3]byte{0xd0, 0xb2, 0x00}}, + {2, [3]byte{0xd1, 0x8c, 0x00}}, {2, [3]byte{0xd1, 0x8b, 0x00}}, + {2, [3]byte{0xd0, 0xb7, 0x00}}, {2, [3]byte{0xd1, 0x88, 0x00}}, + {2, [3]byte{0xd1, 0x8d, 0x00}}, {2, [3]byte{0xd1, 0x89, 0x00}}, + {2, [3]byte{0xd1, 0x87, 0x00}}, {2, [3]byte{0xd1, 0x8a, 0x00}}, + {2, [3]byte{0xd0, 0xae, 0x00}}, {2, [3]byte{0xd0, 0x90, 0x00}}, + {2, [3]byte{0xd0, 0x91, 0x00}}, {2, [3]byte{0xd0, 0xa6, 0x00}}, + {2, [3]byte{0xd0, 0x94, 0x00}}, {2, [3]byte{0xd0, 0x95, 0x00}}, + {2, [3]byte{0xd0, 0xa4, 0x00}}, {2, [3]byte{0xd0, 0x93, 0x00}}, + {2, [3]byte{0xd0, 0xa5, 0x00}}, {2, [3]byte{0xd0, 0x98, 0x00}}, + {2, [3]byte{0xd0, 0x99, 0x00}}, {2, [3]byte{0xd0, 0x9a, 0x00}}, + {2, [3]byte{0xd0, 0x9b, 0x00}}, {2, [3]byte{0xd0, 0x9c, 0x00}}, + {2, [3]byte{0xd0, 0x9d, 0x00}}, {2, [3]byte{0xd0, 0x9e, 0x00}}, + {2, [3]byte{0xd0, 0x9f, 0x00}}, {2, [3]byte{0xd0, 0xaf, 0x00}}, + {2, [3]byte{0xd0, 0xa0, 0x00}}, {2, [3]byte{0xd0, 0xa1, 0x00}}, + {2, [3]byte{0xd0, 0xa2, 0x00}}, {2, [3]byte{0xd0, 0xa3, 0x00}}, + {2, [3]byte{0xd0, 0x96, 0x00}}, {2, [3]byte{0xd0, 0x92, 0x00}}, + {2, [3]byte{0xd0, 0xac, 0x00}}, {2, [3]byte{0xd0, 0xab, 0x00}}, + {2, [3]byte{0xd0, 0x97, 0x00}}, {2, [3]byte{0xd0, 0xa8, 0x00}}, + {2, [3]byte{0xd0, 0xad, 0x00}}, {2, [3]byte{0xd0, 0xa9, 0x00}}, + {2, [3]byte{0xd0, 0xa7, 0x00}}, {2, [3]byte{0xd0, 0xaa, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0x9a0000a0, 0xbf0000a9, 0x9c0000b0, 0x9d0000b2, 0x9e0000b7, 0x9f0000f7, 0xb3000401, 0xe1000410, + 0xe2000411, 0xf7000412, 0xe7000413, 0xe4000414, 0xe5000415, 0xf6000416, 0xfa000417, 0xe9000418, + 0xea000419, 0xeb00041a, 0xec00041b, 0xed00041c, 0xee00041d, 0xef00041e, 0xf000041f, 0xf2000420, + 0xf3000421, 0xf4000422, 0xf5000423, 0xe6000424, 0xe8000425, 0xe3000426, 0xfe000427, 0xfb000428, + 0xfd000429, 0xff00042a, 0xf900042b, 0xf800042c, 0xfc00042d, 0xe000042e, 0xf100042f, 0xc1000430, + 0xc2000431, 0xd7000432, 0xc7000433, 0xc4000434, 0xc5000435, 0xd6000436, 0xda000437, 0xc9000438, + 0xca000439, 0xcb00043a, 0xcc00043b, 0xcd00043c, 0xce00043d, 0xcf00043e, 0xd000043f, 0xd2000440, + 0xd3000441, 0xd4000442, 0xd5000443, 0xc6000444, 0xc8000445, 0xc3000446, 0xde000447, 0xdb000448, + 0xdd000449, 0xdf00044a, 0xd900044b, 0xd800044c, 0xdc00044d, 0xc000044e, 0xd100044f, 0xa3000451, + 0x95002219, 0x9600221a, 0x97002248, 0x98002264, 0x99002265, 0x93002320, 0x9b002321, 0x80002500, + 0x81002502, 0x8200250c, 0x83002510, 0x84002514, 0x85002518, 0x8600251c, 0x87002524, 0x8800252c, + 0x89002534, 0x8a00253c, 0xa0002550, 0xa1002551, 0xa2002552, 0xa4002553, 0xa5002554, 0xa6002555, + 0xa7002556, 0xa8002557, 0xa9002558, 0xaa002559, 0xab00255a, 0xac00255b, 0xad00255c, 0xae00255d, + 0xaf00255e, 0xb000255f, 0xb1002560, 0xb2002561, 0xb4002562, 0xb5002563, 0xb6002564, 0xb7002565, + 0xb8002566, 0xb9002567, 0xba002568, 0xbb002569, 0xbc00256a, 0xbd00256b, 0xbe00256c, 0x8b002580, + 0x8c002584, 0x8d002588, 0x8e00258c, 0x8f002590, 0x90002591, 0x91002592, 0x92002593, 0x940025a0, + }, +} + +// KOI8U is the KOI8-U encoding. +var KOI8U *Charmap = &koi8U + +var koi8U = Charmap{ + name: "KOI8-U", + mib: identifier.KOI8U, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {3, [3]byte{0xe2, 0x94, 0x80}}, {3, [3]byte{0xe2, 0x94, 0x82}}, + {3, [3]byte{0xe2, 0x94, 0x8c}}, {3, [3]byte{0xe2, 0x94, 0x90}}, + {3, [3]byte{0xe2, 0x94, 0x94}}, {3, [3]byte{0xe2, 0x94, 0x98}}, + {3, [3]byte{0xe2, 0x94, 0x9c}}, {3, [3]byte{0xe2, 0x94, 0xa4}}, + {3, [3]byte{0xe2, 0x94, 0xac}}, {3, [3]byte{0xe2, 0x94, 0xb4}}, + {3, [3]byte{0xe2, 0x94, 0xbc}}, {3, [3]byte{0xe2, 0x96, 0x80}}, + {3, [3]byte{0xe2, 0x96, 0x84}}, {3, [3]byte{0xe2, 0x96, 0x88}}, + {3, [3]byte{0xe2, 0x96, 0x8c}}, {3, [3]byte{0xe2, 0x96, 0x90}}, + {3, [3]byte{0xe2, 0x96, 0x91}}, {3, [3]byte{0xe2, 0x96, 0x92}}, + {3, [3]byte{0xe2, 0x96, 0x93}}, {3, [3]byte{0xe2, 0x8c, 0xa0}}, + {3, [3]byte{0xe2, 0x96, 0xa0}}, {3, [3]byte{0xe2, 0x88, 0x99}}, + {3, [3]byte{0xe2, 0x88, 0x9a}}, {3, [3]byte{0xe2, 0x89, 0x88}}, + {3, [3]byte{0xe2, 0x89, 0xa4}}, {3, [3]byte{0xe2, 0x89, 0xa5}}, + {2, [3]byte{0xc2, 0xa0, 0x00}}, {3, [3]byte{0xe2, 0x8c, 0xa1}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {2, [3]byte{0xc2, 0xb2, 0x00}}, + {2, [3]byte{0xc2, 0xb7, 0x00}}, {2, [3]byte{0xc3, 0xb7, 0x00}}, + {3, [3]byte{0xe2, 0x95, 0x90}}, {3, [3]byte{0xe2, 0x95, 0x91}}, + {3, [3]byte{0xe2, 0x95, 0x92}}, {2, [3]byte{0xd1, 0x91, 0x00}}, + {2, [3]byte{0xd1, 0x94, 0x00}}, {3, [3]byte{0xe2, 0x95, 0x94}}, + {2, [3]byte{0xd1, 0x96, 0x00}}, {2, [3]byte{0xd1, 0x97, 0x00}}, + {3, [3]byte{0xe2, 0x95, 0x97}}, {3, [3]byte{0xe2, 0x95, 0x98}}, + {3, [3]byte{0xe2, 0x95, 0x99}}, {3, [3]byte{0xe2, 0x95, 0x9a}}, + {3, [3]byte{0xe2, 0x95, 0x9b}}, {2, [3]byte{0xd2, 0x91, 0x00}}, + {2, [3]byte{0xd1, 0x9e, 0x00}}, {3, [3]byte{0xe2, 0x95, 0x9e}}, + {3, [3]byte{0xe2, 0x95, 0x9f}}, {3, [3]byte{0xe2, 0x95, 0xa0}}, + {3, [3]byte{0xe2, 0x95, 0xa1}}, {2, [3]byte{0xd0, 0x81, 0x00}}, + {2, [3]byte{0xd0, 0x84, 0x00}}, {3, [3]byte{0xe2, 0x95, 0xa3}}, + {2, [3]byte{0xd0, 0x86, 0x00}}, {2, [3]byte{0xd0, 0x87, 0x00}}, + {3, [3]byte{0xe2, 0x95, 0xa6}}, {3, [3]byte{0xe2, 0x95, 0xa7}}, + {3, [3]byte{0xe2, 0x95, 0xa8}}, {3, [3]byte{0xe2, 0x95, 0xa9}}, + {3, [3]byte{0xe2, 0x95, 0xaa}}, {2, [3]byte{0xd2, 0x90, 0x00}}, + {2, [3]byte{0xd0, 0x8e, 0x00}}, {2, [3]byte{0xc2, 0xa9, 0x00}}, + {2, [3]byte{0xd1, 0x8e, 0x00}}, {2, [3]byte{0xd0, 0xb0, 0x00}}, + {2, [3]byte{0xd0, 0xb1, 0x00}}, {2, [3]byte{0xd1, 0x86, 0x00}}, + {2, [3]byte{0xd0, 0xb4, 0x00}}, {2, [3]byte{0xd0, 0xb5, 0x00}}, + {2, [3]byte{0xd1, 0x84, 0x00}}, {2, [3]byte{0xd0, 0xb3, 0x00}}, + {2, [3]byte{0xd1, 0x85, 0x00}}, {2, [3]byte{0xd0, 0xb8, 0x00}}, + {2, [3]byte{0xd0, 0xb9, 0x00}}, {2, [3]byte{0xd0, 0xba, 0x00}}, + {2, [3]byte{0xd0, 0xbb, 0x00}}, {2, [3]byte{0xd0, 0xbc, 0x00}}, + {2, [3]byte{0xd0, 0xbd, 0x00}}, {2, [3]byte{0xd0, 0xbe, 0x00}}, + {2, [3]byte{0xd0, 0xbf, 0x00}}, {2, [3]byte{0xd1, 0x8f, 0x00}}, + {2, [3]byte{0xd1, 0x80, 0x00}}, {2, [3]byte{0xd1, 0x81, 0x00}}, + {2, [3]byte{0xd1, 0x82, 0x00}}, {2, [3]byte{0xd1, 0x83, 0x00}}, + {2, [3]byte{0xd0, 0xb6, 0x00}}, {2, [3]byte{0xd0, 0xb2, 0x00}}, + {2, [3]byte{0xd1, 0x8c, 0x00}}, {2, [3]byte{0xd1, 0x8b, 0x00}}, + {2, [3]byte{0xd0, 0xb7, 0x00}}, {2, [3]byte{0xd1, 0x88, 0x00}}, + {2, [3]byte{0xd1, 0x8d, 0x00}}, {2, [3]byte{0xd1, 0x89, 0x00}}, + {2, [3]byte{0xd1, 0x87, 0x00}}, {2, [3]byte{0xd1, 0x8a, 0x00}}, + {2, [3]byte{0xd0, 0xae, 0x00}}, {2, [3]byte{0xd0, 0x90, 0x00}}, + {2, [3]byte{0xd0, 0x91, 0x00}}, {2, [3]byte{0xd0, 0xa6, 0x00}}, + {2, [3]byte{0xd0, 0x94, 0x00}}, {2, [3]byte{0xd0, 0x95, 0x00}}, + {2, [3]byte{0xd0, 0xa4, 0x00}}, {2, [3]byte{0xd0, 0x93, 0x00}}, + {2, [3]byte{0xd0, 0xa5, 0x00}}, {2, [3]byte{0xd0, 0x98, 0x00}}, + {2, [3]byte{0xd0, 0x99, 0x00}}, {2, [3]byte{0xd0, 0x9a, 0x00}}, + {2, [3]byte{0xd0, 0x9b, 0x00}}, {2, [3]byte{0xd0, 0x9c, 0x00}}, + {2, [3]byte{0xd0, 0x9d, 0x00}}, {2, [3]byte{0xd0, 0x9e, 0x00}}, + {2, [3]byte{0xd0, 0x9f, 0x00}}, {2, [3]byte{0xd0, 0xaf, 0x00}}, + {2, [3]byte{0xd0, 0xa0, 0x00}}, {2, [3]byte{0xd0, 0xa1, 0x00}}, + {2, [3]byte{0xd0, 0xa2, 0x00}}, {2, [3]byte{0xd0, 0xa3, 0x00}}, + {2, [3]byte{0xd0, 0x96, 0x00}}, {2, [3]byte{0xd0, 0x92, 0x00}}, + {2, [3]byte{0xd0, 0xac, 0x00}}, {2, [3]byte{0xd0, 0xab, 0x00}}, + {2, [3]byte{0xd0, 0x97, 0x00}}, {2, [3]byte{0xd0, 0xa8, 0x00}}, + {2, [3]byte{0xd0, 0xad, 0x00}}, {2, [3]byte{0xd0, 0xa9, 0x00}}, + {2, [3]byte{0xd0, 0xa7, 0x00}}, {2, [3]byte{0xd0, 0xaa, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0x9a0000a0, 0xbf0000a9, 0x9c0000b0, 0x9d0000b2, 0x9e0000b7, 0x9f0000f7, 0xb3000401, 0xb4000404, + 0xb6000406, 0xb7000407, 0xbe00040e, 0xe1000410, 0xe2000411, 0xf7000412, 0xe7000413, 0xe4000414, + 0xe5000415, 0xf6000416, 0xfa000417, 0xe9000418, 0xea000419, 0xeb00041a, 0xec00041b, 0xed00041c, + 0xee00041d, 0xef00041e, 0xf000041f, 0xf2000420, 0xf3000421, 0xf4000422, 0xf5000423, 0xe6000424, + 0xe8000425, 0xe3000426, 0xfe000427, 0xfb000428, 0xfd000429, 0xff00042a, 0xf900042b, 0xf800042c, + 0xfc00042d, 0xe000042e, 0xf100042f, 0xc1000430, 0xc2000431, 0xd7000432, 0xc7000433, 0xc4000434, + 0xc5000435, 0xd6000436, 0xda000437, 0xc9000438, 0xca000439, 0xcb00043a, 0xcc00043b, 0xcd00043c, + 0xce00043d, 0xcf00043e, 0xd000043f, 0xd2000440, 0xd3000441, 0xd4000442, 0xd5000443, 0xc6000444, + 0xc8000445, 0xc3000446, 0xde000447, 0xdb000448, 0xdd000449, 0xdf00044a, 0xd900044b, 0xd800044c, + 0xdc00044d, 0xc000044e, 0xd100044f, 0xa3000451, 0xa4000454, 0xa6000456, 0xa7000457, 0xae00045e, + 0xbd000490, 0xad000491, 0x95002219, 0x9600221a, 0x97002248, 0x98002264, 0x99002265, 0x93002320, + 0x9b002321, 0x80002500, 0x81002502, 0x8200250c, 0x83002510, 0x84002514, 0x85002518, 0x8600251c, + 0x87002524, 0x8800252c, 0x89002534, 0x8a00253c, 0xa0002550, 0xa1002551, 0xa2002552, 0xa5002554, + 0xa8002557, 0xa9002558, 0xaa002559, 0xab00255a, 0xac00255b, 0xaf00255e, 0xb000255f, 0xb1002560, + 0xb2002561, 0xb5002563, 0xb8002566, 0xb9002567, 0xba002568, 0xbb002569, 0xbc00256a, 0x8b002580, + 0x8c002584, 0x8d002588, 0x8e00258c, 0x8f002590, 0x90002591, 0x91002592, 0x92002593, 0x940025a0, + }, +} + +// Macintosh is the Macintosh encoding. +var Macintosh *Charmap = &macintosh + +var macintosh = Charmap{ + name: "Macintosh", + mib: identifier.Macintosh, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {2, [3]byte{0xc3, 0x84, 0x00}}, {2, [3]byte{0xc3, 0x85, 0x00}}, + {2, [3]byte{0xc3, 0x87, 0x00}}, {2, [3]byte{0xc3, 0x89, 0x00}}, + {2, [3]byte{0xc3, 0x91, 0x00}}, {2, [3]byte{0xc3, 0x96, 0x00}}, + {2, [3]byte{0xc3, 0x9c, 0x00}}, {2, [3]byte{0xc3, 0xa1, 0x00}}, + {2, [3]byte{0xc3, 0xa0, 0x00}}, {2, [3]byte{0xc3, 0xa2, 0x00}}, + {2, [3]byte{0xc3, 0xa4, 0x00}}, {2, [3]byte{0xc3, 0xa3, 0x00}}, + {2, [3]byte{0xc3, 0xa5, 0x00}}, {2, [3]byte{0xc3, 0xa7, 0x00}}, + {2, [3]byte{0xc3, 0xa9, 0x00}}, {2, [3]byte{0xc3, 0xa8, 0x00}}, + {2, [3]byte{0xc3, 0xaa, 0x00}}, {2, [3]byte{0xc3, 0xab, 0x00}}, + {2, [3]byte{0xc3, 0xad, 0x00}}, {2, [3]byte{0xc3, 0xac, 0x00}}, + {2, [3]byte{0xc3, 0xae, 0x00}}, {2, [3]byte{0xc3, 0xaf, 0x00}}, + {2, [3]byte{0xc3, 0xb1, 0x00}}, {2, [3]byte{0xc3, 0xb3, 0x00}}, + {2, [3]byte{0xc3, 0xb2, 0x00}}, {2, [3]byte{0xc3, 0xb4, 0x00}}, + {2, [3]byte{0xc3, 0xb6, 0x00}}, {2, [3]byte{0xc3, 0xb5, 0x00}}, + {2, [3]byte{0xc3, 0xba, 0x00}}, {2, [3]byte{0xc3, 0xb9, 0x00}}, + {2, [3]byte{0xc3, 0xbb, 0x00}}, {2, [3]byte{0xc3, 0xbc, 0x00}}, + {3, [3]byte{0xe2, 0x80, 0xa0}}, {2, [3]byte{0xc2, 0xb0, 0x00}}, + {2, [3]byte{0xc2, 0xa2, 0x00}}, {2, [3]byte{0xc2, 0xa3, 0x00}}, + {2, [3]byte{0xc2, 0xa7, 0x00}}, {3, [3]byte{0xe2, 0x80, 0xa2}}, + {2, [3]byte{0xc2, 0xb6, 0x00}}, {2, [3]byte{0xc3, 0x9f, 0x00}}, + {2, [3]byte{0xc2, 0xae, 0x00}}, {2, [3]byte{0xc2, 0xa9, 0x00}}, + {3, [3]byte{0xe2, 0x84, 0xa2}}, {2, [3]byte{0xc2, 0xb4, 0x00}}, + {2, [3]byte{0xc2, 0xa8, 0x00}}, {3, [3]byte{0xe2, 0x89, 0xa0}}, + {2, [3]byte{0xc3, 0x86, 0x00}}, {2, [3]byte{0xc3, 0x98, 0x00}}, + {3, [3]byte{0xe2, 0x88, 0x9e}}, {2, [3]byte{0xc2, 0xb1, 0x00}}, + {3, [3]byte{0xe2, 0x89, 0xa4}}, {3, [3]byte{0xe2, 0x89, 0xa5}}, + {2, [3]byte{0xc2, 0xa5, 0x00}}, {2, [3]byte{0xc2, 0xb5, 0x00}}, + {3, [3]byte{0xe2, 0x88, 0x82}}, {3, [3]byte{0xe2, 0x88, 0x91}}, + {3, [3]byte{0xe2, 0x88, 0x8f}}, {2, [3]byte{0xcf, 0x80, 0x00}}, + {3, [3]byte{0xe2, 0x88, 0xab}}, {2, [3]byte{0xc2, 0xaa, 0x00}}, + {2, [3]byte{0xc2, 0xba, 0x00}}, {2, [3]byte{0xce, 0xa9, 0x00}}, + {2, [3]byte{0xc3, 0xa6, 0x00}}, {2, [3]byte{0xc3, 0xb8, 0x00}}, + {2, [3]byte{0xc2, 0xbf, 0x00}}, {2, [3]byte{0xc2, 0xa1, 0x00}}, + {2, [3]byte{0xc2, 0xac, 0x00}}, {3, [3]byte{0xe2, 0x88, 0x9a}}, + {2, [3]byte{0xc6, 0x92, 0x00}}, {3, [3]byte{0xe2, 0x89, 0x88}}, + {3, [3]byte{0xe2, 0x88, 0x86}}, {2, [3]byte{0xc2, 0xab, 0x00}}, + {2, [3]byte{0xc2, 0xbb, 0x00}}, {3, [3]byte{0xe2, 0x80, 0xa6}}, + {2, [3]byte{0xc2, 0xa0, 0x00}}, {2, [3]byte{0xc3, 0x80, 0x00}}, + {2, [3]byte{0xc3, 0x83, 0x00}}, {2, [3]byte{0xc3, 0x95, 0x00}}, + {2, [3]byte{0xc5, 0x92, 0x00}}, {2, [3]byte{0xc5, 0x93, 0x00}}, + {3, [3]byte{0xe2, 0x80, 0x93}}, {3, [3]byte{0xe2, 0x80, 0x94}}, + {3, [3]byte{0xe2, 0x80, 0x9c}}, {3, [3]byte{0xe2, 0x80, 0x9d}}, + {3, [3]byte{0xe2, 0x80, 0x98}}, {3, [3]byte{0xe2, 0x80, 0x99}}, + {2, [3]byte{0xc3, 0xb7, 0x00}}, {3, [3]byte{0xe2, 0x97, 0x8a}}, + {2, [3]byte{0xc3, 0xbf, 0x00}}, {2, [3]byte{0xc5, 0xb8, 0x00}}, + {3, [3]byte{0xe2, 0x81, 0x84}}, {3, [3]byte{0xe2, 0x82, 0xac}}, + {3, [3]byte{0xe2, 0x80, 0xb9}}, {3, [3]byte{0xe2, 0x80, 0xba}}, + {3, [3]byte{0xef, 0xac, 0x81}}, {3, [3]byte{0xef, 0xac, 0x82}}, + {3, [3]byte{0xe2, 0x80, 0xa1}}, {2, [3]byte{0xc2, 0xb7, 0x00}}, + {3, [3]byte{0xe2, 0x80, 0x9a}}, {3, [3]byte{0xe2, 0x80, 0x9e}}, + {3, [3]byte{0xe2, 0x80, 0xb0}}, {2, [3]byte{0xc3, 0x82, 0x00}}, + {2, [3]byte{0xc3, 0x8a, 0x00}}, {2, [3]byte{0xc3, 0x81, 0x00}}, + {2, [3]byte{0xc3, 0x8b, 0x00}}, {2, [3]byte{0xc3, 0x88, 0x00}}, + {2, [3]byte{0xc3, 0x8d, 0x00}}, {2, [3]byte{0xc3, 0x8e, 0x00}}, + {2, [3]byte{0xc3, 0x8f, 0x00}}, {2, [3]byte{0xc3, 0x8c, 0x00}}, + {2, [3]byte{0xc3, 0x93, 0x00}}, {2, [3]byte{0xc3, 0x94, 0x00}}, + {3, [3]byte{0xef, 0xa3, 0xbf}}, {2, [3]byte{0xc3, 0x92, 0x00}}, + {2, [3]byte{0xc3, 0x9a, 0x00}}, {2, [3]byte{0xc3, 0x9b, 0x00}}, + {2, [3]byte{0xc3, 0x99, 0x00}}, {2, [3]byte{0xc4, 0xb1, 0x00}}, + {2, [3]byte{0xcb, 0x86, 0x00}}, {2, [3]byte{0xcb, 0x9c, 0x00}}, + {2, [3]byte{0xc2, 0xaf, 0x00}}, {2, [3]byte{0xcb, 0x98, 0x00}}, + {2, [3]byte{0xcb, 0x99, 0x00}}, {2, [3]byte{0xcb, 0x9a, 0x00}}, + {2, [3]byte{0xc2, 0xb8, 0x00}}, {2, [3]byte{0xcb, 0x9d, 0x00}}, + {2, [3]byte{0xcb, 0x9b, 0x00}}, {2, [3]byte{0xcb, 0x87, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xca0000a0, 0xc10000a1, 0xa20000a2, 0xa30000a3, 0xb40000a5, 0xa40000a7, 0xac0000a8, 0xa90000a9, + 0xbb0000aa, 0xc70000ab, 0xc20000ac, 0xa80000ae, 0xf80000af, 0xa10000b0, 0xb10000b1, 0xab0000b4, + 0xb50000b5, 0xa60000b6, 0xe10000b7, 0xfc0000b8, 0xbc0000ba, 0xc80000bb, 0xc00000bf, 0xcb0000c0, + 0xe70000c1, 0xe50000c2, 0xcc0000c3, 0x800000c4, 0x810000c5, 0xae0000c6, 0x820000c7, 0xe90000c8, + 0x830000c9, 0xe60000ca, 0xe80000cb, 0xed0000cc, 0xea0000cd, 0xeb0000ce, 0xec0000cf, 0x840000d1, + 0xf10000d2, 0xee0000d3, 0xef0000d4, 0xcd0000d5, 0x850000d6, 0xaf0000d8, 0xf40000d9, 0xf20000da, + 0xf30000db, 0x860000dc, 0xa70000df, 0x880000e0, 0x870000e1, 0x890000e2, 0x8b0000e3, 0x8a0000e4, + 0x8c0000e5, 0xbe0000e6, 0x8d0000e7, 0x8f0000e8, 0x8e0000e9, 0x900000ea, 0x910000eb, 0x930000ec, + 0x920000ed, 0x940000ee, 0x950000ef, 0x960000f1, 0x980000f2, 0x970000f3, 0x990000f4, 0x9b0000f5, + 0x9a0000f6, 0xd60000f7, 0xbf0000f8, 0x9d0000f9, 0x9c0000fa, 0x9e0000fb, 0x9f0000fc, 0xd80000ff, + 0xf5000131, 0xce000152, 0xcf000153, 0xd9000178, 0xc4000192, 0xf60002c6, 0xff0002c7, 0xf90002d8, + 0xfa0002d9, 0xfb0002da, 0xfe0002db, 0xf70002dc, 0xfd0002dd, 0xbd0003a9, 0xb90003c0, 0xd0002013, + 0xd1002014, 0xd4002018, 0xd5002019, 0xe200201a, 0xd200201c, 0xd300201d, 0xe300201e, 0xa0002020, + 0xe0002021, 0xa5002022, 0xc9002026, 0xe4002030, 0xdc002039, 0xdd00203a, 0xda002044, 0xdb0020ac, + 0xaa002122, 0xb6002202, 0xc6002206, 0xb800220f, 0xb7002211, 0xc300221a, 0xb000221e, 0xba00222b, + 0xc5002248, 0xad002260, 0xb2002264, 0xb3002265, 0xd70025ca, 0xf000f8ff, 0xde00fb01, 0xdf00fb02, + }, +} + +// MacintoshCyrillic is the Macintosh Cyrillic encoding. +var MacintoshCyrillic *Charmap = &macintoshCyrillic + +var macintoshCyrillic = Charmap{ + name: "Macintosh Cyrillic", + mib: identifier.MacintoshCyrillic, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {2, [3]byte{0xd0, 0x90, 0x00}}, {2, [3]byte{0xd0, 0x91, 0x00}}, + {2, [3]byte{0xd0, 0x92, 0x00}}, {2, [3]byte{0xd0, 0x93, 0x00}}, + {2, [3]byte{0xd0, 0x94, 0x00}}, {2, [3]byte{0xd0, 0x95, 0x00}}, + {2, [3]byte{0xd0, 0x96, 0x00}}, {2, [3]byte{0xd0, 0x97, 0x00}}, + {2, [3]byte{0xd0, 0x98, 0x00}}, {2, [3]byte{0xd0, 0x99, 0x00}}, + {2, [3]byte{0xd0, 0x9a, 0x00}}, {2, [3]byte{0xd0, 0x9b, 0x00}}, + {2, [3]byte{0xd0, 0x9c, 0x00}}, {2, [3]byte{0xd0, 0x9d, 0x00}}, + {2, [3]byte{0xd0, 0x9e, 0x00}}, {2, [3]byte{0xd0, 0x9f, 0x00}}, + {2, [3]byte{0xd0, 0xa0, 0x00}}, {2, [3]byte{0xd0, 0xa1, 0x00}}, + {2, [3]byte{0xd0, 0xa2, 0x00}}, {2, [3]byte{0xd0, 0xa3, 0x00}}, + {2, [3]byte{0xd0, 0xa4, 0x00}}, {2, [3]byte{0xd0, 0xa5, 0x00}}, + {2, [3]byte{0xd0, 0xa6, 0x00}}, {2, [3]byte{0xd0, 0xa7, 0x00}}, + {2, [3]byte{0xd0, 0xa8, 0x00}}, {2, [3]byte{0xd0, 0xa9, 0x00}}, + {2, [3]byte{0xd0, 0xaa, 0x00}}, {2, [3]byte{0xd0, 0xab, 0x00}}, + {2, [3]byte{0xd0, 0xac, 0x00}}, {2, [3]byte{0xd0, 0xad, 0x00}}, + {2, [3]byte{0xd0, 0xae, 0x00}}, {2, [3]byte{0xd0, 0xaf, 0x00}}, + {3, [3]byte{0xe2, 0x80, 0xa0}}, {2, [3]byte{0xc2, 0xb0, 0x00}}, + {2, [3]byte{0xd2, 0x90, 0x00}}, {2, [3]byte{0xc2, 0xa3, 0x00}}, + {2, [3]byte{0xc2, 0xa7, 0x00}}, {3, [3]byte{0xe2, 0x80, 0xa2}}, + {2, [3]byte{0xc2, 0xb6, 0x00}}, {2, [3]byte{0xd0, 0x86, 0x00}}, + {2, [3]byte{0xc2, 0xae, 0x00}}, {2, [3]byte{0xc2, 0xa9, 0x00}}, + {3, [3]byte{0xe2, 0x84, 0xa2}}, {2, [3]byte{0xd0, 0x82, 0x00}}, + {2, [3]byte{0xd1, 0x92, 0x00}}, {3, [3]byte{0xe2, 0x89, 0xa0}}, + {2, [3]byte{0xd0, 0x83, 0x00}}, {2, [3]byte{0xd1, 0x93, 0x00}}, + {3, [3]byte{0xe2, 0x88, 0x9e}}, {2, [3]byte{0xc2, 0xb1, 0x00}}, + {3, [3]byte{0xe2, 0x89, 0xa4}}, {3, [3]byte{0xe2, 0x89, 0xa5}}, + {2, [3]byte{0xd1, 0x96, 0x00}}, {2, [3]byte{0xc2, 0xb5, 0x00}}, + {2, [3]byte{0xd2, 0x91, 0x00}}, {2, [3]byte{0xd0, 0x88, 0x00}}, + {2, [3]byte{0xd0, 0x84, 0x00}}, {2, [3]byte{0xd1, 0x94, 0x00}}, + {2, [3]byte{0xd0, 0x87, 0x00}}, {2, [3]byte{0xd1, 0x97, 0x00}}, + {2, [3]byte{0xd0, 0x89, 0x00}}, {2, [3]byte{0xd1, 0x99, 0x00}}, + {2, [3]byte{0xd0, 0x8a, 0x00}}, {2, [3]byte{0xd1, 0x9a, 0x00}}, + {2, [3]byte{0xd1, 0x98, 0x00}}, {2, [3]byte{0xd0, 0x85, 0x00}}, + {2, [3]byte{0xc2, 0xac, 0x00}}, {3, [3]byte{0xe2, 0x88, 0x9a}}, + {2, [3]byte{0xc6, 0x92, 0x00}}, {3, [3]byte{0xe2, 0x89, 0x88}}, + {3, [3]byte{0xe2, 0x88, 0x86}}, {2, [3]byte{0xc2, 0xab, 0x00}}, + {2, [3]byte{0xc2, 0xbb, 0x00}}, {3, [3]byte{0xe2, 0x80, 0xa6}}, + {2, [3]byte{0xc2, 0xa0, 0x00}}, {2, [3]byte{0xd0, 0x8b, 0x00}}, + {2, [3]byte{0xd1, 0x9b, 0x00}}, {2, [3]byte{0xd0, 0x8c, 0x00}}, + {2, [3]byte{0xd1, 0x9c, 0x00}}, {2, [3]byte{0xd1, 0x95, 0x00}}, + {3, [3]byte{0xe2, 0x80, 0x93}}, {3, [3]byte{0xe2, 0x80, 0x94}}, + {3, [3]byte{0xe2, 0x80, 0x9c}}, {3, [3]byte{0xe2, 0x80, 0x9d}}, + {3, [3]byte{0xe2, 0x80, 0x98}}, {3, [3]byte{0xe2, 0x80, 0x99}}, + {2, [3]byte{0xc3, 0xb7, 0x00}}, {3, [3]byte{0xe2, 0x80, 0x9e}}, + {2, [3]byte{0xd0, 0x8e, 0x00}}, {2, [3]byte{0xd1, 0x9e, 0x00}}, + {2, [3]byte{0xd0, 0x8f, 0x00}}, {2, [3]byte{0xd1, 0x9f, 0x00}}, + {3, [3]byte{0xe2, 0x84, 0x96}}, {2, [3]byte{0xd0, 0x81, 0x00}}, + {2, [3]byte{0xd1, 0x91, 0x00}}, {2, [3]byte{0xd1, 0x8f, 0x00}}, + {2, [3]byte{0xd0, 0xb0, 0x00}}, {2, [3]byte{0xd0, 0xb1, 0x00}}, + {2, [3]byte{0xd0, 0xb2, 0x00}}, {2, [3]byte{0xd0, 0xb3, 0x00}}, + {2, [3]byte{0xd0, 0xb4, 0x00}}, {2, [3]byte{0xd0, 0xb5, 0x00}}, + {2, [3]byte{0xd0, 0xb6, 0x00}}, {2, [3]byte{0xd0, 0xb7, 0x00}}, + {2, [3]byte{0xd0, 0xb8, 0x00}}, {2, [3]byte{0xd0, 0xb9, 0x00}}, + {2, [3]byte{0xd0, 0xba, 0x00}}, {2, [3]byte{0xd0, 0xbb, 0x00}}, + {2, [3]byte{0xd0, 0xbc, 0x00}}, {2, [3]byte{0xd0, 0xbd, 0x00}}, + {2, [3]byte{0xd0, 0xbe, 0x00}}, {2, [3]byte{0xd0, 0xbf, 0x00}}, + {2, [3]byte{0xd1, 0x80, 0x00}}, {2, [3]byte{0xd1, 0x81, 0x00}}, + {2, [3]byte{0xd1, 0x82, 0x00}}, {2, [3]byte{0xd1, 0x83, 0x00}}, + {2, [3]byte{0xd1, 0x84, 0x00}}, {2, [3]byte{0xd1, 0x85, 0x00}}, + {2, [3]byte{0xd1, 0x86, 0x00}}, {2, [3]byte{0xd1, 0x87, 0x00}}, + {2, [3]byte{0xd1, 0x88, 0x00}}, {2, [3]byte{0xd1, 0x89, 0x00}}, + {2, [3]byte{0xd1, 0x8a, 0x00}}, {2, [3]byte{0xd1, 0x8b, 0x00}}, + {2, [3]byte{0xd1, 0x8c, 0x00}}, {2, [3]byte{0xd1, 0x8d, 0x00}}, + {2, [3]byte{0xd1, 0x8e, 0x00}}, {3, [3]byte{0xe2, 0x82, 0xac}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xca0000a0, 0xa30000a3, 0xa40000a7, 0xa90000a9, 0xc70000ab, 0xc20000ac, 0xa80000ae, 0xa10000b0, + 0xb10000b1, 0xb50000b5, 0xa60000b6, 0xc80000bb, 0xd60000f7, 0xc4000192, 0xdd000401, 0xab000402, + 0xae000403, 0xb8000404, 0xc1000405, 0xa7000406, 0xba000407, 0xb7000408, 0xbc000409, 0xbe00040a, + 0xcb00040b, 0xcd00040c, 0xd800040e, 0xda00040f, 0x80000410, 0x81000411, 0x82000412, 0x83000413, + 0x84000414, 0x85000415, 0x86000416, 0x87000417, 0x88000418, 0x89000419, 0x8a00041a, 0x8b00041b, + 0x8c00041c, 0x8d00041d, 0x8e00041e, 0x8f00041f, 0x90000420, 0x91000421, 0x92000422, 0x93000423, + 0x94000424, 0x95000425, 0x96000426, 0x97000427, 0x98000428, 0x99000429, 0x9a00042a, 0x9b00042b, + 0x9c00042c, 0x9d00042d, 0x9e00042e, 0x9f00042f, 0xe0000430, 0xe1000431, 0xe2000432, 0xe3000433, + 0xe4000434, 0xe5000435, 0xe6000436, 0xe7000437, 0xe8000438, 0xe9000439, 0xea00043a, 0xeb00043b, + 0xec00043c, 0xed00043d, 0xee00043e, 0xef00043f, 0xf0000440, 0xf1000441, 0xf2000442, 0xf3000443, + 0xf4000444, 0xf5000445, 0xf6000446, 0xf7000447, 0xf8000448, 0xf9000449, 0xfa00044a, 0xfb00044b, + 0xfc00044c, 0xfd00044d, 0xfe00044e, 0xdf00044f, 0xde000451, 0xac000452, 0xaf000453, 0xb9000454, + 0xcf000455, 0xb4000456, 0xbb000457, 0xc0000458, 0xbd000459, 0xbf00045a, 0xcc00045b, 0xce00045c, + 0xd900045e, 0xdb00045f, 0xa2000490, 0xb6000491, 0xd0002013, 0xd1002014, 0xd4002018, 0xd5002019, + 0xd200201c, 0xd300201d, 0xd700201e, 0xa0002020, 0xa5002022, 0xc9002026, 0xff0020ac, 0xdc002116, + 0xaa002122, 0xc6002206, 0xc300221a, 0xb000221e, 0xc5002248, 0xad002260, 0xb2002264, 0xb3002265, + }, +} + +// Windows874 is the Windows 874 encoding. +var Windows874 *Charmap = &windows874 + +var windows874 = Charmap{ + name: "Windows 874", + mib: identifier.Windows874, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {3, [3]byte{0xe2, 0x82, 0xac}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xe2, 0x80, 0xa6}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xe2, 0x80, 0x98}}, + {3, [3]byte{0xe2, 0x80, 0x99}}, {3, [3]byte{0xe2, 0x80, 0x9c}}, + {3, [3]byte{0xe2, 0x80, 0x9d}}, {3, [3]byte{0xe2, 0x80, 0xa2}}, + {3, [3]byte{0xe2, 0x80, 0x93}}, {3, [3]byte{0xe2, 0x80, 0x94}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {2, [3]byte{0xc2, 0xa0, 0x00}}, {3, [3]byte{0xe0, 0xb8, 0x81}}, + {3, [3]byte{0xe0, 0xb8, 0x82}}, {3, [3]byte{0xe0, 0xb8, 0x83}}, + {3, [3]byte{0xe0, 0xb8, 0x84}}, {3, [3]byte{0xe0, 0xb8, 0x85}}, + {3, [3]byte{0xe0, 0xb8, 0x86}}, {3, [3]byte{0xe0, 0xb8, 0x87}}, + {3, [3]byte{0xe0, 0xb8, 0x88}}, {3, [3]byte{0xe0, 0xb8, 0x89}}, + {3, [3]byte{0xe0, 0xb8, 0x8a}}, {3, [3]byte{0xe0, 0xb8, 0x8b}}, + {3, [3]byte{0xe0, 0xb8, 0x8c}}, {3, [3]byte{0xe0, 0xb8, 0x8d}}, + {3, [3]byte{0xe0, 0xb8, 0x8e}}, {3, [3]byte{0xe0, 0xb8, 0x8f}}, + {3, [3]byte{0xe0, 0xb8, 0x90}}, {3, [3]byte{0xe0, 0xb8, 0x91}}, + {3, [3]byte{0xe0, 0xb8, 0x92}}, {3, [3]byte{0xe0, 0xb8, 0x93}}, + {3, [3]byte{0xe0, 0xb8, 0x94}}, {3, [3]byte{0xe0, 0xb8, 0x95}}, + {3, [3]byte{0xe0, 0xb8, 0x96}}, {3, [3]byte{0xe0, 0xb8, 0x97}}, + {3, [3]byte{0xe0, 0xb8, 0x98}}, {3, [3]byte{0xe0, 0xb8, 0x99}}, + {3, [3]byte{0xe0, 0xb8, 0x9a}}, {3, [3]byte{0xe0, 0xb8, 0x9b}}, + {3, [3]byte{0xe0, 0xb8, 0x9c}}, {3, [3]byte{0xe0, 0xb8, 0x9d}}, + {3, [3]byte{0xe0, 0xb8, 0x9e}}, {3, [3]byte{0xe0, 0xb8, 0x9f}}, + {3, [3]byte{0xe0, 0xb8, 0xa0}}, {3, [3]byte{0xe0, 0xb8, 0xa1}}, + {3, [3]byte{0xe0, 0xb8, 0xa2}}, {3, [3]byte{0xe0, 0xb8, 0xa3}}, + {3, [3]byte{0xe0, 0xb8, 0xa4}}, {3, [3]byte{0xe0, 0xb8, 0xa5}}, + {3, [3]byte{0xe0, 0xb8, 0xa6}}, {3, [3]byte{0xe0, 0xb8, 0xa7}}, + {3, [3]byte{0xe0, 0xb8, 0xa8}}, {3, [3]byte{0xe0, 0xb8, 0xa9}}, + {3, [3]byte{0xe0, 0xb8, 0xaa}}, {3, [3]byte{0xe0, 0xb8, 0xab}}, + {3, [3]byte{0xe0, 0xb8, 0xac}}, {3, [3]byte{0xe0, 0xb8, 0xad}}, + {3, [3]byte{0xe0, 0xb8, 0xae}}, {3, [3]byte{0xe0, 0xb8, 0xaf}}, + {3, [3]byte{0xe0, 0xb8, 0xb0}}, {3, [3]byte{0xe0, 0xb8, 0xb1}}, + {3, [3]byte{0xe0, 0xb8, 0xb2}}, {3, [3]byte{0xe0, 0xb8, 0xb3}}, + {3, [3]byte{0xe0, 0xb8, 0xb4}}, {3, [3]byte{0xe0, 0xb8, 0xb5}}, + {3, [3]byte{0xe0, 0xb8, 0xb6}}, {3, [3]byte{0xe0, 0xb8, 0xb7}}, + {3, [3]byte{0xe0, 0xb8, 0xb8}}, {3, [3]byte{0xe0, 0xb8, 0xb9}}, + {3, [3]byte{0xe0, 0xb8, 0xba}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xe0, 0xb8, 0xbf}}, + {3, [3]byte{0xe0, 0xb9, 0x80}}, {3, [3]byte{0xe0, 0xb9, 0x81}}, + {3, [3]byte{0xe0, 0xb9, 0x82}}, {3, [3]byte{0xe0, 0xb9, 0x83}}, + {3, [3]byte{0xe0, 0xb9, 0x84}}, {3, [3]byte{0xe0, 0xb9, 0x85}}, + {3, [3]byte{0xe0, 0xb9, 0x86}}, {3, [3]byte{0xe0, 0xb9, 0x87}}, + {3, [3]byte{0xe0, 0xb9, 0x88}}, {3, [3]byte{0xe0, 0xb9, 0x89}}, + {3, [3]byte{0xe0, 0xb9, 0x8a}}, {3, [3]byte{0xe0, 0xb9, 0x8b}}, + {3, [3]byte{0xe0, 0xb9, 0x8c}}, {3, [3]byte{0xe0, 0xb9, 0x8d}}, + {3, [3]byte{0xe0, 0xb9, 0x8e}}, {3, [3]byte{0xe0, 0xb9, 0x8f}}, + {3, [3]byte{0xe0, 0xb9, 0x90}}, {3, [3]byte{0xe0, 0xb9, 0x91}}, + {3, [3]byte{0xe0, 0xb9, 0x92}}, {3, [3]byte{0xe0, 0xb9, 0x93}}, + {3, [3]byte{0xe0, 0xb9, 0x94}}, {3, [3]byte{0xe0, 0xb9, 0x95}}, + {3, [3]byte{0xe0, 0xb9, 0x96}}, {3, [3]byte{0xe0, 0xb9, 0x97}}, + {3, [3]byte{0xe0, 0xb9, 0x98}}, {3, [3]byte{0xe0, 0xb9, 0x99}}, + {3, [3]byte{0xe0, 0xb9, 0x9a}}, {3, [3]byte{0xe0, 0xb9, 0x9b}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xa00000a0, 0xa1000e01, 0xa2000e02, 0xa3000e03, 0xa4000e04, 0xa5000e05, 0xa6000e06, 0xa7000e07, + 0xa8000e08, 0xa9000e09, 0xaa000e0a, 0xab000e0b, 0xac000e0c, 0xad000e0d, 0xae000e0e, 0xaf000e0f, + 0xb0000e10, 0xb1000e11, 0xb2000e12, 0xb3000e13, 0xb4000e14, 0xb5000e15, 0xb6000e16, 0xb7000e17, + 0xb8000e18, 0xb9000e19, 0xba000e1a, 0xbb000e1b, 0xbc000e1c, 0xbd000e1d, 0xbe000e1e, 0xbf000e1f, + 0xc0000e20, 0xc1000e21, 0xc2000e22, 0xc3000e23, 0xc4000e24, 0xc5000e25, 0xc6000e26, 0xc7000e27, + 0xc8000e28, 0xc9000e29, 0xca000e2a, 0xcb000e2b, 0xcc000e2c, 0xcd000e2d, 0xce000e2e, 0xcf000e2f, + 0xd0000e30, 0xd1000e31, 0xd2000e32, 0xd3000e33, 0xd4000e34, 0xd5000e35, 0xd6000e36, 0xd7000e37, + 0xd8000e38, 0xd9000e39, 0xda000e3a, 0xdf000e3f, 0xe0000e40, 0xe1000e41, 0xe2000e42, 0xe3000e43, + 0xe4000e44, 0xe5000e45, 0xe6000e46, 0xe7000e47, 0xe8000e48, 0xe9000e49, 0xea000e4a, 0xeb000e4b, + 0xec000e4c, 0xed000e4d, 0xee000e4e, 0xef000e4f, 0xf0000e50, 0xf1000e51, 0xf2000e52, 0xf3000e53, + 0xf4000e54, 0xf5000e55, 0xf6000e56, 0xf7000e57, 0xf8000e58, 0xf9000e59, 0xfa000e5a, 0xfb000e5b, + 0x96002013, 0x97002014, 0x91002018, 0x92002019, 0x9300201c, 0x9400201d, 0x95002022, 0x85002026, + 0x800020ac, 0x800020ac, 0x800020ac, 0x800020ac, 0x800020ac, 0x800020ac, 0x800020ac, 0x800020ac, + 0x800020ac, 0x800020ac, 0x800020ac, 0x800020ac, 0x800020ac, 0x800020ac, 0x800020ac, 0x800020ac, + 0x800020ac, 0x800020ac, 0x800020ac, 0x800020ac, 0x800020ac, 0x800020ac, 0x800020ac, 0x800020ac, + 0x800020ac, 0x800020ac, 0x800020ac, 0x800020ac, 0x800020ac, 0x800020ac, 0x800020ac, 0x800020ac, + }, +} + +// Windows1250 is the Windows 1250 encoding. +var Windows1250 *Charmap = &windows1250 + +var windows1250 = Charmap{ + name: "Windows 1250", + mib: identifier.Windows1250, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {3, [3]byte{0xe2, 0x82, 0xac}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xe2, 0x80, 0x9a}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xe2, 0x80, 0x9e}}, {3, [3]byte{0xe2, 0x80, 0xa6}}, + {3, [3]byte{0xe2, 0x80, 0xa0}}, {3, [3]byte{0xe2, 0x80, 0xa1}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xe2, 0x80, 0xb0}}, + {2, [3]byte{0xc5, 0xa0, 0x00}}, {3, [3]byte{0xe2, 0x80, 0xb9}}, + {2, [3]byte{0xc5, 0x9a, 0x00}}, {2, [3]byte{0xc5, 0xa4, 0x00}}, + {2, [3]byte{0xc5, 0xbd, 0x00}}, {2, [3]byte{0xc5, 0xb9, 0x00}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xe2, 0x80, 0x98}}, + {3, [3]byte{0xe2, 0x80, 0x99}}, {3, [3]byte{0xe2, 0x80, 0x9c}}, + {3, [3]byte{0xe2, 0x80, 0x9d}}, {3, [3]byte{0xe2, 0x80, 0xa2}}, + {3, [3]byte{0xe2, 0x80, 0x93}}, {3, [3]byte{0xe2, 0x80, 0x94}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xe2, 0x84, 0xa2}}, + {2, [3]byte{0xc5, 0xa1, 0x00}}, {3, [3]byte{0xe2, 0x80, 0xba}}, + {2, [3]byte{0xc5, 0x9b, 0x00}}, {2, [3]byte{0xc5, 0xa5, 0x00}}, + {2, [3]byte{0xc5, 0xbe, 0x00}}, {2, [3]byte{0xc5, 0xba, 0x00}}, + {2, [3]byte{0xc2, 0xa0, 0x00}}, {2, [3]byte{0xcb, 0x87, 0x00}}, + {2, [3]byte{0xcb, 0x98, 0x00}}, {2, [3]byte{0xc5, 0x81, 0x00}}, + {2, [3]byte{0xc2, 0xa4, 0x00}}, {2, [3]byte{0xc4, 0x84, 0x00}}, + {2, [3]byte{0xc2, 0xa6, 0x00}}, {2, [3]byte{0xc2, 0xa7, 0x00}}, + {2, [3]byte{0xc2, 0xa8, 0x00}}, {2, [3]byte{0xc2, 0xa9, 0x00}}, + {2, [3]byte{0xc5, 0x9e, 0x00}}, {2, [3]byte{0xc2, 0xab, 0x00}}, + {2, [3]byte{0xc2, 0xac, 0x00}}, {2, [3]byte{0xc2, 0xad, 0x00}}, + {2, [3]byte{0xc2, 0xae, 0x00}}, {2, [3]byte{0xc5, 0xbb, 0x00}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {2, [3]byte{0xc2, 0xb1, 0x00}}, + {2, [3]byte{0xcb, 0x9b, 0x00}}, {2, [3]byte{0xc5, 0x82, 0x00}}, + {2, [3]byte{0xc2, 0xb4, 0x00}}, {2, [3]byte{0xc2, 0xb5, 0x00}}, + {2, [3]byte{0xc2, 0xb6, 0x00}}, {2, [3]byte{0xc2, 0xb7, 0x00}}, + {2, [3]byte{0xc2, 0xb8, 0x00}}, {2, [3]byte{0xc4, 0x85, 0x00}}, + {2, [3]byte{0xc5, 0x9f, 0x00}}, {2, [3]byte{0xc2, 0xbb, 0x00}}, + {2, [3]byte{0xc4, 0xbd, 0x00}}, {2, [3]byte{0xcb, 0x9d, 0x00}}, + {2, [3]byte{0xc4, 0xbe, 0x00}}, {2, [3]byte{0xc5, 0xbc, 0x00}}, + {2, [3]byte{0xc5, 0x94, 0x00}}, {2, [3]byte{0xc3, 0x81, 0x00}}, + {2, [3]byte{0xc3, 0x82, 0x00}}, {2, [3]byte{0xc4, 0x82, 0x00}}, + {2, [3]byte{0xc3, 0x84, 0x00}}, {2, [3]byte{0xc4, 0xb9, 0x00}}, + {2, [3]byte{0xc4, 0x86, 0x00}}, {2, [3]byte{0xc3, 0x87, 0x00}}, + {2, [3]byte{0xc4, 0x8c, 0x00}}, {2, [3]byte{0xc3, 0x89, 0x00}}, + {2, [3]byte{0xc4, 0x98, 0x00}}, {2, [3]byte{0xc3, 0x8b, 0x00}}, + {2, [3]byte{0xc4, 0x9a, 0x00}}, {2, [3]byte{0xc3, 0x8d, 0x00}}, + {2, [3]byte{0xc3, 0x8e, 0x00}}, {2, [3]byte{0xc4, 0x8e, 0x00}}, + {2, [3]byte{0xc4, 0x90, 0x00}}, {2, [3]byte{0xc5, 0x83, 0x00}}, + {2, [3]byte{0xc5, 0x87, 0x00}}, {2, [3]byte{0xc3, 0x93, 0x00}}, + {2, [3]byte{0xc3, 0x94, 0x00}}, {2, [3]byte{0xc5, 0x90, 0x00}}, + {2, [3]byte{0xc3, 0x96, 0x00}}, {2, [3]byte{0xc3, 0x97, 0x00}}, + {2, [3]byte{0xc5, 0x98, 0x00}}, {2, [3]byte{0xc5, 0xae, 0x00}}, + {2, [3]byte{0xc3, 0x9a, 0x00}}, {2, [3]byte{0xc5, 0xb0, 0x00}}, + {2, [3]byte{0xc3, 0x9c, 0x00}}, {2, [3]byte{0xc3, 0x9d, 0x00}}, + {2, [3]byte{0xc5, 0xa2, 0x00}}, {2, [3]byte{0xc3, 0x9f, 0x00}}, + {2, [3]byte{0xc5, 0x95, 0x00}}, {2, [3]byte{0xc3, 0xa1, 0x00}}, + {2, [3]byte{0xc3, 0xa2, 0x00}}, {2, [3]byte{0xc4, 0x83, 0x00}}, + {2, [3]byte{0xc3, 0xa4, 0x00}}, {2, [3]byte{0xc4, 0xba, 0x00}}, + {2, [3]byte{0xc4, 0x87, 0x00}}, {2, [3]byte{0xc3, 0xa7, 0x00}}, + {2, [3]byte{0xc4, 0x8d, 0x00}}, {2, [3]byte{0xc3, 0xa9, 0x00}}, + {2, [3]byte{0xc4, 0x99, 0x00}}, {2, [3]byte{0xc3, 0xab, 0x00}}, + {2, [3]byte{0xc4, 0x9b, 0x00}}, {2, [3]byte{0xc3, 0xad, 0x00}}, + {2, [3]byte{0xc3, 0xae, 0x00}}, {2, [3]byte{0xc4, 0x8f, 0x00}}, + {2, [3]byte{0xc4, 0x91, 0x00}}, {2, [3]byte{0xc5, 0x84, 0x00}}, + {2, [3]byte{0xc5, 0x88, 0x00}}, {2, [3]byte{0xc3, 0xb3, 0x00}}, + {2, [3]byte{0xc3, 0xb4, 0x00}}, {2, [3]byte{0xc5, 0x91, 0x00}}, + {2, [3]byte{0xc3, 0xb6, 0x00}}, {2, [3]byte{0xc3, 0xb7, 0x00}}, + {2, [3]byte{0xc5, 0x99, 0x00}}, {2, [3]byte{0xc5, 0xaf, 0x00}}, + {2, [3]byte{0xc3, 0xba, 0x00}}, {2, [3]byte{0xc5, 0xb1, 0x00}}, + {2, [3]byte{0xc3, 0xbc, 0x00}}, {2, [3]byte{0xc3, 0xbd, 0x00}}, + {2, [3]byte{0xc5, 0xa3, 0x00}}, {2, [3]byte{0xcb, 0x99, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xa00000a0, 0xa40000a4, 0xa60000a6, 0xa70000a7, 0xa80000a8, 0xa90000a9, 0xab0000ab, 0xac0000ac, + 0xad0000ad, 0xae0000ae, 0xb00000b0, 0xb10000b1, 0xb40000b4, 0xb50000b5, 0xb60000b6, 0xb70000b7, + 0xb80000b8, 0xbb0000bb, 0xc10000c1, 0xc20000c2, 0xc40000c4, 0xc70000c7, 0xc90000c9, 0xcb0000cb, + 0xcd0000cd, 0xce0000ce, 0xd30000d3, 0xd40000d4, 0xd60000d6, 0xd70000d7, 0xda0000da, 0xdc0000dc, + 0xdd0000dd, 0xdf0000df, 0xe10000e1, 0xe20000e2, 0xe40000e4, 0xe70000e7, 0xe90000e9, 0xeb0000eb, + 0xed0000ed, 0xee0000ee, 0xf30000f3, 0xf40000f4, 0xf60000f6, 0xf70000f7, 0xfa0000fa, 0xfc0000fc, + 0xfd0000fd, 0xc3000102, 0xe3000103, 0xa5000104, 0xb9000105, 0xc6000106, 0xe6000107, 0xc800010c, + 0xe800010d, 0xcf00010e, 0xef00010f, 0xd0000110, 0xf0000111, 0xca000118, 0xea000119, 0xcc00011a, + 0xec00011b, 0xc5000139, 0xe500013a, 0xbc00013d, 0xbe00013e, 0xa3000141, 0xb3000142, 0xd1000143, + 0xf1000144, 0xd2000147, 0xf2000148, 0xd5000150, 0xf5000151, 0xc0000154, 0xe0000155, 0xd8000158, + 0xf8000159, 0x8c00015a, 0x9c00015b, 0xaa00015e, 0xba00015f, 0x8a000160, 0x9a000161, 0xde000162, + 0xfe000163, 0x8d000164, 0x9d000165, 0xd900016e, 0xf900016f, 0xdb000170, 0xfb000171, 0x8f000179, + 0x9f00017a, 0xaf00017b, 0xbf00017c, 0x8e00017d, 0x9e00017e, 0xa10002c7, 0xa20002d8, 0xff0002d9, + 0xb20002db, 0xbd0002dd, 0x96002013, 0x97002014, 0x91002018, 0x92002019, 0x8200201a, 0x9300201c, + 0x9400201d, 0x8400201e, 0x86002020, 0x87002021, 0x95002022, 0x85002026, 0x89002030, 0x8b002039, + 0x9b00203a, 0x800020ac, 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, + }, +} + +// Windows1251 is the Windows 1251 encoding. +var Windows1251 *Charmap = &windows1251 + +var windows1251 = Charmap{ + name: "Windows 1251", + mib: identifier.Windows1251, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {2, [3]byte{0xd0, 0x82, 0x00}}, {2, [3]byte{0xd0, 0x83, 0x00}}, + {3, [3]byte{0xe2, 0x80, 0x9a}}, {2, [3]byte{0xd1, 0x93, 0x00}}, + {3, [3]byte{0xe2, 0x80, 0x9e}}, {3, [3]byte{0xe2, 0x80, 0xa6}}, + {3, [3]byte{0xe2, 0x80, 0xa0}}, {3, [3]byte{0xe2, 0x80, 0xa1}}, + {3, [3]byte{0xe2, 0x82, 0xac}}, {3, [3]byte{0xe2, 0x80, 0xb0}}, + {2, [3]byte{0xd0, 0x89, 0x00}}, {3, [3]byte{0xe2, 0x80, 0xb9}}, + {2, [3]byte{0xd0, 0x8a, 0x00}}, {2, [3]byte{0xd0, 0x8c, 0x00}}, + {2, [3]byte{0xd0, 0x8b, 0x00}}, {2, [3]byte{0xd0, 0x8f, 0x00}}, + {2, [3]byte{0xd1, 0x92, 0x00}}, {3, [3]byte{0xe2, 0x80, 0x98}}, + {3, [3]byte{0xe2, 0x80, 0x99}}, {3, [3]byte{0xe2, 0x80, 0x9c}}, + {3, [3]byte{0xe2, 0x80, 0x9d}}, {3, [3]byte{0xe2, 0x80, 0xa2}}, + {3, [3]byte{0xe2, 0x80, 0x93}}, {3, [3]byte{0xe2, 0x80, 0x94}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xe2, 0x84, 0xa2}}, + {2, [3]byte{0xd1, 0x99, 0x00}}, {3, [3]byte{0xe2, 0x80, 0xba}}, + {2, [3]byte{0xd1, 0x9a, 0x00}}, {2, [3]byte{0xd1, 0x9c, 0x00}}, + {2, [3]byte{0xd1, 0x9b, 0x00}}, {2, [3]byte{0xd1, 0x9f, 0x00}}, + {2, [3]byte{0xc2, 0xa0, 0x00}}, {2, [3]byte{0xd0, 0x8e, 0x00}}, + {2, [3]byte{0xd1, 0x9e, 0x00}}, {2, [3]byte{0xd0, 0x88, 0x00}}, + {2, [3]byte{0xc2, 0xa4, 0x00}}, {2, [3]byte{0xd2, 0x90, 0x00}}, + {2, [3]byte{0xc2, 0xa6, 0x00}}, {2, [3]byte{0xc2, 0xa7, 0x00}}, + {2, [3]byte{0xd0, 0x81, 0x00}}, {2, [3]byte{0xc2, 0xa9, 0x00}}, + {2, [3]byte{0xd0, 0x84, 0x00}}, {2, [3]byte{0xc2, 0xab, 0x00}}, + {2, [3]byte{0xc2, 0xac, 0x00}}, {2, [3]byte{0xc2, 0xad, 0x00}}, + {2, [3]byte{0xc2, 0xae, 0x00}}, {2, [3]byte{0xd0, 0x87, 0x00}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {2, [3]byte{0xc2, 0xb1, 0x00}}, + {2, [3]byte{0xd0, 0x86, 0x00}}, {2, [3]byte{0xd1, 0x96, 0x00}}, + {2, [3]byte{0xd2, 0x91, 0x00}}, {2, [3]byte{0xc2, 0xb5, 0x00}}, + {2, [3]byte{0xc2, 0xb6, 0x00}}, {2, [3]byte{0xc2, 0xb7, 0x00}}, + {2, [3]byte{0xd1, 0x91, 0x00}}, {3, [3]byte{0xe2, 0x84, 0x96}}, + {2, [3]byte{0xd1, 0x94, 0x00}}, {2, [3]byte{0xc2, 0xbb, 0x00}}, + {2, [3]byte{0xd1, 0x98, 0x00}}, {2, [3]byte{0xd0, 0x85, 0x00}}, + {2, [3]byte{0xd1, 0x95, 0x00}}, {2, [3]byte{0xd1, 0x97, 0x00}}, + {2, [3]byte{0xd0, 0x90, 0x00}}, {2, [3]byte{0xd0, 0x91, 0x00}}, + {2, [3]byte{0xd0, 0x92, 0x00}}, {2, [3]byte{0xd0, 0x93, 0x00}}, + {2, [3]byte{0xd0, 0x94, 0x00}}, {2, [3]byte{0xd0, 0x95, 0x00}}, + {2, [3]byte{0xd0, 0x96, 0x00}}, {2, [3]byte{0xd0, 0x97, 0x00}}, + {2, [3]byte{0xd0, 0x98, 0x00}}, {2, [3]byte{0xd0, 0x99, 0x00}}, + {2, [3]byte{0xd0, 0x9a, 0x00}}, {2, [3]byte{0xd0, 0x9b, 0x00}}, + {2, [3]byte{0xd0, 0x9c, 0x00}}, {2, [3]byte{0xd0, 0x9d, 0x00}}, + {2, [3]byte{0xd0, 0x9e, 0x00}}, {2, [3]byte{0xd0, 0x9f, 0x00}}, + {2, [3]byte{0xd0, 0xa0, 0x00}}, {2, [3]byte{0xd0, 0xa1, 0x00}}, + {2, [3]byte{0xd0, 0xa2, 0x00}}, {2, [3]byte{0xd0, 0xa3, 0x00}}, + {2, [3]byte{0xd0, 0xa4, 0x00}}, {2, [3]byte{0xd0, 0xa5, 0x00}}, + {2, [3]byte{0xd0, 0xa6, 0x00}}, {2, [3]byte{0xd0, 0xa7, 0x00}}, + {2, [3]byte{0xd0, 0xa8, 0x00}}, {2, [3]byte{0xd0, 0xa9, 0x00}}, + {2, [3]byte{0xd0, 0xaa, 0x00}}, {2, [3]byte{0xd0, 0xab, 0x00}}, + {2, [3]byte{0xd0, 0xac, 0x00}}, {2, [3]byte{0xd0, 0xad, 0x00}}, + {2, [3]byte{0xd0, 0xae, 0x00}}, {2, [3]byte{0xd0, 0xaf, 0x00}}, + {2, [3]byte{0xd0, 0xb0, 0x00}}, {2, [3]byte{0xd0, 0xb1, 0x00}}, + {2, [3]byte{0xd0, 0xb2, 0x00}}, {2, [3]byte{0xd0, 0xb3, 0x00}}, + {2, [3]byte{0xd0, 0xb4, 0x00}}, {2, [3]byte{0xd0, 0xb5, 0x00}}, + {2, [3]byte{0xd0, 0xb6, 0x00}}, {2, [3]byte{0xd0, 0xb7, 0x00}}, + {2, [3]byte{0xd0, 0xb8, 0x00}}, {2, [3]byte{0xd0, 0xb9, 0x00}}, + {2, [3]byte{0xd0, 0xba, 0x00}}, {2, [3]byte{0xd0, 0xbb, 0x00}}, + {2, [3]byte{0xd0, 0xbc, 0x00}}, {2, [3]byte{0xd0, 0xbd, 0x00}}, + {2, [3]byte{0xd0, 0xbe, 0x00}}, {2, [3]byte{0xd0, 0xbf, 0x00}}, + {2, [3]byte{0xd1, 0x80, 0x00}}, {2, [3]byte{0xd1, 0x81, 0x00}}, + {2, [3]byte{0xd1, 0x82, 0x00}}, {2, [3]byte{0xd1, 0x83, 0x00}}, + {2, [3]byte{0xd1, 0x84, 0x00}}, {2, [3]byte{0xd1, 0x85, 0x00}}, + {2, [3]byte{0xd1, 0x86, 0x00}}, {2, [3]byte{0xd1, 0x87, 0x00}}, + {2, [3]byte{0xd1, 0x88, 0x00}}, {2, [3]byte{0xd1, 0x89, 0x00}}, + {2, [3]byte{0xd1, 0x8a, 0x00}}, {2, [3]byte{0xd1, 0x8b, 0x00}}, + {2, [3]byte{0xd1, 0x8c, 0x00}}, {2, [3]byte{0xd1, 0x8d, 0x00}}, + {2, [3]byte{0xd1, 0x8e, 0x00}}, {2, [3]byte{0xd1, 0x8f, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xa00000a0, 0xa40000a4, 0xa60000a6, 0xa70000a7, 0xa90000a9, 0xab0000ab, 0xac0000ac, 0xad0000ad, + 0xae0000ae, 0xb00000b0, 0xb10000b1, 0xb50000b5, 0xb60000b6, 0xb70000b7, 0xbb0000bb, 0xa8000401, + 0x80000402, 0x81000403, 0xaa000404, 0xbd000405, 0xb2000406, 0xaf000407, 0xa3000408, 0x8a000409, + 0x8c00040a, 0x8e00040b, 0x8d00040c, 0xa100040e, 0x8f00040f, 0xc0000410, 0xc1000411, 0xc2000412, + 0xc3000413, 0xc4000414, 0xc5000415, 0xc6000416, 0xc7000417, 0xc8000418, 0xc9000419, 0xca00041a, + 0xcb00041b, 0xcc00041c, 0xcd00041d, 0xce00041e, 0xcf00041f, 0xd0000420, 0xd1000421, 0xd2000422, + 0xd3000423, 0xd4000424, 0xd5000425, 0xd6000426, 0xd7000427, 0xd8000428, 0xd9000429, 0xda00042a, + 0xdb00042b, 0xdc00042c, 0xdd00042d, 0xde00042e, 0xdf00042f, 0xe0000430, 0xe1000431, 0xe2000432, + 0xe3000433, 0xe4000434, 0xe5000435, 0xe6000436, 0xe7000437, 0xe8000438, 0xe9000439, 0xea00043a, + 0xeb00043b, 0xec00043c, 0xed00043d, 0xee00043e, 0xef00043f, 0xf0000440, 0xf1000441, 0xf2000442, + 0xf3000443, 0xf4000444, 0xf5000445, 0xf6000446, 0xf7000447, 0xf8000448, 0xf9000449, 0xfa00044a, + 0xfb00044b, 0xfc00044c, 0xfd00044d, 0xfe00044e, 0xff00044f, 0xb8000451, 0x90000452, 0x83000453, + 0xba000454, 0xbe000455, 0xb3000456, 0xbf000457, 0xbc000458, 0x9a000459, 0x9c00045a, 0x9e00045b, + 0x9d00045c, 0xa200045e, 0x9f00045f, 0xa5000490, 0xb4000491, 0x96002013, 0x97002014, 0x91002018, + 0x92002019, 0x8200201a, 0x9300201c, 0x9400201d, 0x8400201e, 0x86002020, 0x87002021, 0x95002022, + 0x85002026, 0x89002030, 0x8b002039, 0x9b00203a, 0x880020ac, 0xb9002116, 0x99002122, 0x99002122, + }, +} + +// Windows1252 is the Windows 1252 encoding. +var Windows1252 *Charmap = &windows1252 + +var windows1252 = Charmap{ + name: "Windows 1252", + mib: identifier.Windows1252, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {3, [3]byte{0xe2, 0x82, 0xac}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xe2, 0x80, 0x9a}}, {2, [3]byte{0xc6, 0x92, 0x00}}, + {3, [3]byte{0xe2, 0x80, 0x9e}}, {3, [3]byte{0xe2, 0x80, 0xa6}}, + {3, [3]byte{0xe2, 0x80, 0xa0}}, {3, [3]byte{0xe2, 0x80, 0xa1}}, + {2, [3]byte{0xcb, 0x86, 0x00}}, {3, [3]byte{0xe2, 0x80, 0xb0}}, + {2, [3]byte{0xc5, 0xa0, 0x00}}, {3, [3]byte{0xe2, 0x80, 0xb9}}, + {2, [3]byte{0xc5, 0x92, 0x00}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {2, [3]byte{0xc5, 0xbd, 0x00}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xe2, 0x80, 0x98}}, + {3, [3]byte{0xe2, 0x80, 0x99}}, {3, [3]byte{0xe2, 0x80, 0x9c}}, + {3, [3]byte{0xe2, 0x80, 0x9d}}, {3, [3]byte{0xe2, 0x80, 0xa2}}, + {3, [3]byte{0xe2, 0x80, 0x93}}, {3, [3]byte{0xe2, 0x80, 0x94}}, + {2, [3]byte{0xcb, 0x9c, 0x00}}, {3, [3]byte{0xe2, 0x84, 0xa2}}, + {2, [3]byte{0xc5, 0xa1, 0x00}}, {3, [3]byte{0xe2, 0x80, 0xba}}, + {2, [3]byte{0xc5, 0x93, 0x00}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {2, [3]byte{0xc5, 0xbe, 0x00}}, {2, [3]byte{0xc5, 0xb8, 0x00}}, + {2, [3]byte{0xc2, 0xa0, 0x00}}, {2, [3]byte{0xc2, 0xa1, 0x00}}, + {2, [3]byte{0xc2, 0xa2, 0x00}}, {2, [3]byte{0xc2, 0xa3, 0x00}}, + {2, [3]byte{0xc2, 0xa4, 0x00}}, {2, [3]byte{0xc2, 0xa5, 0x00}}, + {2, [3]byte{0xc2, 0xa6, 0x00}}, {2, [3]byte{0xc2, 0xa7, 0x00}}, + {2, [3]byte{0xc2, 0xa8, 0x00}}, {2, [3]byte{0xc2, 0xa9, 0x00}}, + {2, [3]byte{0xc2, 0xaa, 0x00}}, {2, [3]byte{0xc2, 0xab, 0x00}}, + {2, [3]byte{0xc2, 0xac, 0x00}}, {2, [3]byte{0xc2, 0xad, 0x00}}, + {2, [3]byte{0xc2, 0xae, 0x00}}, {2, [3]byte{0xc2, 0xaf, 0x00}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {2, [3]byte{0xc2, 0xb1, 0x00}}, + {2, [3]byte{0xc2, 0xb2, 0x00}}, {2, [3]byte{0xc2, 0xb3, 0x00}}, + {2, [3]byte{0xc2, 0xb4, 0x00}}, {2, [3]byte{0xc2, 0xb5, 0x00}}, + {2, [3]byte{0xc2, 0xb6, 0x00}}, {2, [3]byte{0xc2, 0xb7, 0x00}}, + {2, [3]byte{0xc2, 0xb8, 0x00}}, {2, [3]byte{0xc2, 0xb9, 0x00}}, + {2, [3]byte{0xc2, 0xba, 0x00}}, {2, [3]byte{0xc2, 0xbb, 0x00}}, + {2, [3]byte{0xc2, 0xbc, 0x00}}, {2, [3]byte{0xc2, 0xbd, 0x00}}, + {2, [3]byte{0xc2, 0xbe, 0x00}}, {2, [3]byte{0xc2, 0xbf, 0x00}}, + {2, [3]byte{0xc3, 0x80, 0x00}}, {2, [3]byte{0xc3, 0x81, 0x00}}, + {2, [3]byte{0xc3, 0x82, 0x00}}, {2, [3]byte{0xc3, 0x83, 0x00}}, + {2, [3]byte{0xc3, 0x84, 0x00}}, {2, [3]byte{0xc3, 0x85, 0x00}}, + {2, [3]byte{0xc3, 0x86, 0x00}}, {2, [3]byte{0xc3, 0x87, 0x00}}, + {2, [3]byte{0xc3, 0x88, 0x00}}, {2, [3]byte{0xc3, 0x89, 0x00}}, + {2, [3]byte{0xc3, 0x8a, 0x00}}, {2, [3]byte{0xc3, 0x8b, 0x00}}, + {2, [3]byte{0xc3, 0x8c, 0x00}}, {2, [3]byte{0xc3, 0x8d, 0x00}}, + {2, [3]byte{0xc3, 0x8e, 0x00}}, {2, [3]byte{0xc3, 0x8f, 0x00}}, + {2, [3]byte{0xc3, 0x90, 0x00}}, {2, [3]byte{0xc3, 0x91, 0x00}}, + {2, [3]byte{0xc3, 0x92, 0x00}}, {2, [3]byte{0xc3, 0x93, 0x00}}, + {2, [3]byte{0xc3, 0x94, 0x00}}, {2, [3]byte{0xc3, 0x95, 0x00}}, + {2, [3]byte{0xc3, 0x96, 0x00}}, {2, [3]byte{0xc3, 0x97, 0x00}}, + {2, [3]byte{0xc3, 0x98, 0x00}}, {2, [3]byte{0xc3, 0x99, 0x00}}, + {2, [3]byte{0xc3, 0x9a, 0x00}}, {2, [3]byte{0xc3, 0x9b, 0x00}}, + {2, [3]byte{0xc3, 0x9c, 0x00}}, {2, [3]byte{0xc3, 0x9d, 0x00}}, + {2, [3]byte{0xc3, 0x9e, 0x00}}, {2, [3]byte{0xc3, 0x9f, 0x00}}, + {2, [3]byte{0xc3, 0xa0, 0x00}}, {2, [3]byte{0xc3, 0xa1, 0x00}}, + {2, [3]byte{0xc3, 0xa2, 0x00}}, {2, [3]byte{0xc3, 0xa3, 0x00}}, + {2, [3]byte{0xc3, 0xa4, 0x00}}, {2, [3]byte{0xc3, 0xa5, 0x00}}, + {2, [3]byte{0xc3, 0xa6, 0x00}}, {2, [3]byte{0xc3, 0xa7, 0x00}}, + {2, [3]byte{0xc3, 0xa8, 0x00}}, {2, [3]byte{0xc3, 0xa9, 0x00}}, + {2, [3]byte{0xc3, 0xaa, 0x00}}, {2, [3]byte{0xc3, 0xab, 0x00}}, + {2, [3]byte{0xc3, 0xac, 0x00}}, {2, [3]byte{0xc3, 0xad, 0x00}}, + {2, [3]byte{0xc3, 0xae, 0x00}}, {2, [3]byte{0xc3, 0xaf, 0x00}}, + {2, [3]byte{0xc3, 0xb0, 0x00}}, {2, [3]byte{0xc3, 0xb1, 0x00}}, + {2, [3]byte{0xc3, 0xb2, 0x00}}, {2, [3]byte{0xc3, 0xb3, 0x00}}, + {2, [3]byte{0xc3, 0xb4, 0x00}}, {2, [3]byte{0xc3, 0xb5, 0x00}}, + {2, [3]byte{0xc3, 0xb6, 0x00}}, {2, [3]byte{0xc3, 0xb7, 0x00}}, + {2, [3]byte{0xc3, 0xb8, 0x00}}, {2, [3]byte{0xc3, 0xb9, 0x00}}, + {2, [3]byte{0xc3, 0xba, 0x00}}, {2, [3]byte{0xc3, 0xbb, 0x00}}, + {2, [3]byte{0xc3, 0xbc, 0x00}}, {2, [3]byte{0xc3, 0xbd, 0x00}}, + {2, [3]byte{0xc3, 0xbe, 0x00}}, {2, [3]byte{0xc3, 0xbf, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xa00000a0, 0xa10000a1, 0xa20000a2, 0xa30000a3, 0xa40000a4, 0xa50000a5, 0xa60000a6, 0xa70000a7, + 0xa80000a8, 0xa90000a9, 0xaa0000aa, 0xab0000ab, 0xac0000ac, 0xad0000ad, 0xae0000ae, 0xaf0000af, + 0xb00000b0, 0xb10000b1, 0xb20000b2, 0xb30000b3, 0xb40000b4, 0xb50000b5, 0xb60000b6, 0xb70000b7, + 0xb80000b8, 0xb90000b9, 0xba0000ba, 0xbb0000bb, 0xbc0000bc, 0xbd0000bd, 0xbe0000be, 0xbf0000bf, + 0xc00000c0, 0xc10000c1, 0xc20000c2, 0xc30000c3, 0xc40000c4, 0xc50000c5, 0xc60000c6, 0xc70000c7, + 0xc80000c8, 0xc90000c9, 0xca0000ca, 0xcb0000cb, 0xcc0000cc, 0xcd0000cd, 0xce0000ce, 0xcf0000cf, + 0xd00000d0, 0xd10000d1, 0xd20000d2, 0xd30000d3, 0xd40000d4, 0xd50000d5, 0xd60000d6, 0xd70000d7, + 0xd80000d8, 0xd90000d9, 0xda0000da, 0xdb0000db, 0xdc0000dc, 0xdd0000dd, 0xde0000de, 0xdf0000df, + 0xe00000e0, 0xe10000e1, 0xe20000e2, 0xe30000e3, 0xe40000e4, 0xe50000e5, 0xe60000e6, 0xe70000e7, + 0xe80000e8, 0xe90000e9, 0xea0000ea, 0xeb0000eb, 0xec0000ec, 0xed0000ed, 0xee0000ee, 0xef0000ef, + 0xf00000f0, 0xf10000f1, 0xf20000f2, 0xf30000f3, 0xf40000f4, 0xf50000f5, 0xf60000f6, 0xf70000f7, + 0xf80000f8, 0xf90000f9, 0xfa0000fa, 0xfb0000fb, 0xfc0000fc, 0xfd0000fd, 0xfe0000fe, 0xff0000ff, + 0x8c000152, 0x9c000153, 0x8a000160, 0x9a000161, 0x9f000178, 0x8e00017d, 0x9e00017e, 0x83000192, + 0x880002c6, 0x980002dc, 0x96002013, 0x97002014, 0x91002018, 0x92002019, 0x8200201a, 0x9300201c, + 0x9400201d, 0x8400201e, 0x86002020, 0x87002021, 0x95002022, 0x85002026, 0x89002030, 0x8b002039, + 0x9b00203a, 0x800020ac, 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, + }, +} + +// Windows1253 is the Windows 1253 encoding. +var Windows1253 *Charmap = &windows1253 + +var windows1253 = Charmap{ + name: "Windows 1253", + mib: identifier.Windows1253, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {3, [3]byte{0xe2, 0x82, 0xac}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xe2, 0x80, 0x9a}}, {2, [3]byte{0xc6, 0x92, 0x00}}, + {3, [3]byte{0xe2, 0x80, 0x9e}}, {3, [3]byte{0xe2, 0x80, 0xa6}}, + {3, [3]byte{0xe2, 0x80, 0xa0}}, {3, [3]byte{0xe2, 0x80, 0xa1}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xe2, 0x80, 0xb0}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xe2, 0x80, 0xb9}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xe2, 0x80, 0x98}}, + {3, [3]byte{0xe2, 0x80, 0x99}}, {3, [3]byte{0xe2, 0x80, 0x9c}}, + {3, [3]byte{0xe2, 0x80, 0x9d}}, {3, [3]byte{0xe2, 0x80, 0xa2}}, + {3, [3]byte{0xe2, 0x80, 0x93}}, {3, [3]byte{0xe2, 0x80, 0x94}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xe2, 0x84, 0xa2}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xe2, 0x80, 0xba}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {2, [3]byte{0xc2, 0xa0, 0x00}}, {2, [3]byte{0xce, 0x85, 0x00}}, + {2, [3]byte{0xce, 0x86, 0x00}}, {2, [3]byte{0xc2, 0xa3, 0x00}}, + {2, [3]byte{0xc2, 0xa4, 0x00}}, {2, [3]byte{0xc2, 0xa5, 0x00}}, + {2, [3]byte{0xc2, 0xa6, 0x00}}, {2, [3]byte{0xc2, 0xa7, 0x00}}, + {2, [3]byte{0xc2, 0xa8, 0x00}}, {2, [3]byte{0xc2, 0xa9, 0x00}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {2, [3]byte{0xc2, 0xab, 0x00}}, + {2, [3]byte{0xc2, 0xac, 0x00}}, {2, [3]byte{0xc2, 0xad, 0x00}}, + {2, [3]byte{0xc2, 0xae, 0x00}}, {3, [3]byte{0xe2, 0x80, 0x95}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {2, [3]byte{0xc2, 0xb1, 0x00}}, + {2, [3]byte{0xc2, 0xb2, 0x00}}, {2, [3]byte{0xc2, 0xb3, 0x00}}, + {2, [3]byte{0xce, 0x84, 0x00}}, {2, [3]byte{0xc2, 0xb5, 0x00}}, + {2, [3]byte{0xc2, 0xb6, 0x00}}, {2, [3]byte{0xc2, 0xb7, 0x00}}, + {2, [3]byte{0xce, 0x88, 0x00}}, {2, [3]byte{0xce, 0x89, 0x00}}, + {2, [3]byte{0xce, 0x8a, 0x00}}, {2, [3]byte{0xc2, 0xbb, 0x00}}, + {2, [3]byte{0xce, 0x8c, 0x00}}, {2, [3]byte{0xc2, 0xbd, 0x00}}, + {2, [3]byte{0xce, 0x8e, 0x00}}, {2, [3]byte{0xce, 0x8f, 0x00}}, + {2, [3]byte{0xce, 0x90, 0x00}}, {2, [3]byte{0xce, 0x91, 0x00}}, + {2, [3]byte{0xce, 0x92, 0x00}}, {2, [3]byte{0xce, 0x93, 0x00}}, + {2, [3]byte{0xce, 0x94, 0x00}}, {2, [3]byte{0xce, 0x95, 0x00}}, + {2, [3]byte{0xce, 0x96, 0x00}}, {2, [3]byte{0xce, 0x97, 0x00}}, + {2, [3]byte{0xce, 0x98, 0x00}}, {2, [3]byte{0xce, 0x99, 0x00}}, + {2, [3]byte{0xce, 0x9a, 0x00}}, {2, [3]byte{0xce, 0x9b, 0x00}}, + {2, [3]byte{0xce, 0x9c, 0x00}}, {2, [3]byte{0xce, 0x9d, 0x00}}, + {2, [3]byte{0xce, 0x9e, 0x00}}, {2, [3]byte{0xce, 0x9f, 0x00}}, + {2, [3]byte{0xce, 0xa0, 0x00}}, {2, [3]byte{0xce, 0xa1, 0x00}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {2, [3]byte{0xce, 0xa3, 0x00}}, + {2, [3]byte{0xce, 0xa4, 0x00}}, {2, [3]byte{0xce, 0xa5, 0x00}}, + {2, [3]byte{0xce, 0xa6, 0x00}}, {2, [3]byte{0xce, 0xa7, 0x00}}, + {2, [3]byte{0xce, 0xa8, 0x00}}, {2, [3]byte{0xce, 0xa9, 0x00}}, + {2, [3]byte{0xce, 0xaa, 0x00}}, {2, [3]byte{0xce, 0xab, 0x00}}, + {2, [3]byte{0xce, 0xac, 0x00}}, {2, [3]byte{0xce, 0xad, 0x00}}, + {2, [3]byte{0xce, 0xae, 0x00}}, {2, [3]byte{0xce, 0xaf, 0x00}}, + {2, [3]byte{0xce, 0xb0, 0x00}}, {2, [3]byte{0xce, 0xb1, 0x00}}, + {2, [3]byte{0xce, 0xb2, 0x00}}, {2, [3]byte{0xce, 0xb3, 0x00}}, + {2, [3]byte{0xce, 0xb4, 0x00}}, {2, [3]byte{0xce, 0xb5, 0x00}}, + {2, [3]byte{0xce, 0xb6, 0x00}}, {2, [3]byte{0xce, 0xb7, 0x00}}, + {2, [3]byte{0xce, 0xb8, 0x00}}, {2, [3]byte{0xce, 0xb9, 0x00}}, + {2, [3]byte{0xce, 0xba, 0x00}}, {2, [3]byte{0xce, 0xbb, 0x00}}, + {2, [3]byte{0xce, 0xbc, 0x00}}, {2, [3]byte{0xce, 0xbd, 0x00}}, + {2, [3]byte{0xce, 0xbe, 0x00}}, {2, [3]byte{0xce, 0xbf, 0x00}}, + {2, [3]byte{0xcf, 0x80, 0x00}}, {2, [3]byte{0xcf, 0x81, 0x00}}, + {2, [3]byte{0xcf, 0x82, 0x00}}, {2, [3]byte{0xcf, 0x83, 0x00}}, + {2, [3]byte{0xcf, 0x84, 0x00}}, {2, [3]byte{0xcf, 0x85, 0x00}}, + {2, [3]byte{0xcf, 0x86, 0x00}}, {2, [3]byte{0xcf, 0x87, 0x00}}, + {2, [3]byte{0xcf, 0x88, 0x00}}, {2, [3]byte{0xcf, 0x89, 0x00}}, + {2, [3]byte{0xcf, 0x8a, 0x00}}, {2, [3]byte{0xcf, 0x8b, 0x00}}, + {2, [3]byte{0xcf, 0x8c, 0x00}}, {2, [3]byte{0xcf, 0x8d, 0x00}}, + {2, [3]byte{0xcf, 0x8e, 0x00}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xa00000a0, 0xa30000a3, 0xa40000a4, 0xa50000a5, 0xa60000a6, 0xa70000a7, 0xa80000a8, 0xa90000a9, + 0xab0000ab, 0xac0000ac, 0xad0000ad, 0xae0000ae, 0xb00000b0, 0xb10000b1, 0xb20000b2, 0xb30000b3, + 0xb50000b5, 0xb60000b6, 0xb70000b7, 0xbb0000bb, 0xbd0000bd, 0x83000192, 0xb4000384, 0xa1000385, + 0xa2000386, 0xb8000388, 0xb9000389, 0xba00038a, 0xbc00038c, 0xbe00038e, 0xbf00038f, 0xc0000390, + 0xc1000391, 0xc2000392, 0xc3000393, 0xc4000394, 0xc5000395, 0xc6000396, 0xc7000397, 0xc8000398, + 0xc9000399, 0xca00039a, 0xcb00039b, 0xcc00039c, 0xcd00039d, 0xce00039e, 0xcf00039f, 0xd00003a0, + 0xd10003a1, 0xd30003a3, 0xd40003a4, 0xd50003a5, 0xd60003a6, 0xd70003a7, 0xd80003a8, 0xd90003a9, + 0xda0003aa, 0xdb0003ab, 0xdc0003ac, 0xdd0003ad, 0xde0003ae, 0xdf0003af, 0xe00003b0, 0xe10003b1, + 0xe20003b2, 0xe30003b3, 0xe40003b4, 0xe50003b5, 0xe60003b6, 0xe70003b7, 0xe80003b8, 0xe90003b9, + 0xea0003ba, 0xeb0003bb, 0xec0003bc, 0xed0003bd, 0xee0003be, 0xef0003bf, 0xf00003c0, 0xf10003c1, + 0xf20003c2, 0xf30003c3, 0xf40003c4, 0xf50003c5, 0xf60003c6, 0xf70003c7, 0xf80003c8, 0xf90003c9, + 0xfa0003ca, 0xfb0003cb, 0xfc0003cc, 0xfd0003cd, 0xfe0003ce, 0x96002013, 0x97002014, 0xaf002015, + 0x91002018, 0x92002019, 0x8200201a, 0x9300201c, 0x9400201d, 0x8400201e, 0x86002020, 0x87002021, + 0x95002022, 0x85002026, 0x89002030, 0x8b002039, 0x9b00203a, 0x800020ac, 0x99002122, 0x99002122, + 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, + 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, + }, +} + +// Windows1254 is the Windows 1254 encoding. +var Windows1254 *Charmap = &windows1254 + +var windows1254 = Charmap{ + name: "Windows 1254", + mib: identifier.Windows1254, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {3, [3]byte{0xe2, 0x82, 0xac}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xe2, 0x80, 0x9a}}, {2, [3]byte{0xc6, 0x92, 0x00}}, + {3, [3]byte{0xe2, 0x80, 0x9e}}, {3, [3]byte{0xe2, 0x80, 0xa6}}, + {3, [3]byte{0xe2, 0x80, 0xa0}}, {3, [3]byte{0xe2, 0x80, 0xa1}}, + {2, [3]byte{0xcb, 0x86, 0x00}}, {3, [3]byte{0xe2, 0x80, 0xb0}}, + {2, [3]byte{0xc5, 0xa0, 0x00}}, {3, [3]byte{0xe2, 0x80, 0xb9}}, + {2, [3]byte{0xc5, 0x92, 0x00}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xe2, 0x80, 0x98}}, + {3, [3]byte{0xe2, 0x80, 0x99}}, {3, [3]byte{0xe2, 0x80, 0x9c}}, + {3, [3]byte{0xe2, 0x80, 0x9d}}, {3, [3]byte{0xe2, 0x80, 0xa2}}, + {3, [3]byte{0xe2, 0x80, 0x93}}, {3, [3]byte{0xe2, 0x80, 0x94}}, + {2, [3]byte{0xcb, 0x9c, 0x00}}, {3, [3]byte{0xe2, 0x84, 0xa2}}, + {2, [3]byte{0xc5, 0xa1, 0x00}}, {3, [3]byte{0xe2, 0x80, 0xba}}, + {2, [3]byte{0xc5, 0x93, 0x00}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {2, [3]byte{0xc5, 0xb8, 0x00}}, + {2, [3]byte{0xc2, 0xa0, 0x00}}, {2, [3]byte{0xc2, 0xa1, 0x00}}, + {2, [3]byte{0xc2, 0xa2, 0x00}}, {2, [3]byte{0xc2, 0xa3, 0x00}}, + {2, [3]byte{0xc2, 0xa4, 0x00}}, {2, [3]byte{0xc2, 0xa5, 0x00}}, + {2, [3]byte{0xc2, 0xa6, 0x00}}, {2, [3]byte{0xc2, 0xa7, 0x00}}, + {2, [3]byte{0xc2, 0xa8, 0x00}}, {2, [3]byte{0xc2, 0xa9, 0x00}}, + {2, [3]byte{0xc2, 0xaa, 0x00}}, {2, [3]byte{0xc2, 0xab, 0x00}}, + {2, [3]byte{0xc2, 0xac, 0x00}}, {2, [3]byte{0xc2, 0xad, 0x00}}, + {2, [3]byte{0xc2, 0xae, 0x00}}, {2, [3]byte{0xc2, 0xaf, 0x00}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {2, [3]byte{0xc2, 0xb1, 0x00}}, + {2, [3]byte{0xc2, 0xb2, 0x00}}, {2, [3]byte{0xc2, 0xb3, 0x00}}, + {2, [3]byte{0xc2, 0xb4, 0x00}}, {2, [3]byte{0xc2, 0xb5, 0x00}}, + {2, [3]byte{0xc2, 0xb6, 0x00}}, {2, [3]byte{0xc2, 0xb7, 0x00}}, + {2, [3]byte{0xc2, 0xb8, 0x00}}, {2, [3]byte{0xc2, 0xb9, 0x00}}, + {2, [3]byte{0xc2, 0xba, 0x00}}, {2, [3]byte{0xc2, 0xbb, 0x00}}, + {2, [3]byte{0xc2, 0xbc, 0x00}}, {2, [3]byte{0xc2, 0xbd, 0x00}}, + {2, [3]byte{0xc2, 0xbe, 0x00}}, {2, [3]byte{0xc2, 0xbf, 0x00}}, + {2, [3]byte{0xc3, 0x80, 0x00}}, {2, [3]byte{0xc3, 0x81, 0x00}}, + {2, [3]byte{0xc3, 0x82, 0x00}}, {2, [3]byte{0xc3, 0x83, 0x00}}, + {2, [3]byte{0xc3, 0x84, 0x00}}, {2, [3]byte{0xc3, 0x85, 0x00}}, + {2, [3]byte{0xc3, 0x86, 0x00}}, {2, [3]byte{0xc3, 0x87, 0x00}}, + {2, [3]byte{0xc3, 0x88, 0x00}}, {2, [3]byte{0xc3, 0x89, 0x00}}, + {2, [3]byte{0xc3, 0x8a, 0x00}}, {2, [3]byte{0xc3, 0x8b, 0x00}}, + {2, [3]byte{0xc3, 0x8c, 0x00}}, {2, [3]byte{0xc3, 0x8d, 0x00}}, + {2, [3]byte{0xc3, 0x8e, 0x00}}, {2, [3]byte{0xc3, 0x8f, 0x00}}, + {2, [3]byte{0xc4, 0x9e, 0x00}}, {2, [3]byte{0xc3, 0x91, 0x00}}, + {2, [3]byte{0xc3, 0x92, 0x00}}, {2, [3]byte{0xc3, 0x93, 0x00}}, + {2, [3]byte{0xc3, 0x94, 0x00}}, {2, [3]byte{0xc3, 0x95, 0x00}}, + {2, [3]byte{0xc3, 0x96, 0x00}}, {2, [3]byte{0xc3, 0x97, 0x00}}, + {2, [3]byte{0xc3, 0x98, 0x00}}, {2, [3]byte{0xc3, 0x99, 0x00}}, + {2, [3]byte{0xc3, 0x9a, 0x00}}, {2, [3]byte{0xc3, 0x9b, 0x00}}, + {2, [3]byte{0xc3, 0x9c, 0x00}}, {2, [3]byte{0xc4, 0xb0, 0x00}}, + {2, [3]byte{0xc5, 0x9e, 0x00}}, {2, [3]byte{0xc3, 0x9f, 0x00}}, + {2, [3]byte{0xc3, 0xa0, 0x00}}, {2, [3]byte{0xc3, 0xa1, 0x00}}, + {2, [3]byte{0xc3, 0xa2, 0x00}}, {2, [3]byte{0xc3, 0xa3, 0x00}}, + {2, [3]byte{0xc3, 0xa4, 0x00}}, {2, [3]byte{0xc3, 0xa5, 0x00}}, + {2, [3]byte{0xc3, 0xa6, 0x00}}, {2, [3]byte{0xc3, 0xa7, 0x00}}, + {2, [3]byte{0xc3, 0xa8, 0x00}}, {2, [3]byte{0xc3, 0xa9, 0x00}}, + {2, [3]byte{0xc3, 0xaa, 0x00}}, {2, [3]byte{0xc3, 0xab, 0x00}}, + {2, [3]byte{0xc3, 0xac, 0x00}}, {2, [3]byte{0xc3, 0xad, 0x00}}, + {2, [3]byte{0xc3, 0xae, 0x00}}, {2, [3]byte{0xc3, 0xaf, 0x00}}, + {2, [3]byte{0xc4, 0x9f, 0x00}}, {2, [3]byte{0xc3, 0xb1, 0x00}}, + {2, [3]byte{0xc3, 0xb2, 0x00}}, {2, [3]byte{0xc3, 0xb3, 0x00}}, + {2, [3]byte{0xc3, 0xb4, 0x00}}, {2, [3]byte{0xc3, 0xb5, 0x00}}, + {2, [3]byte{0xc3, 0xb6, 0x00}}, {2, [3]byte{0xc3, 0xb7, 0x00}}, + {2, [3]byte{0xc3, 0xb8, 0x00}}, {2, [3]byte{0xc3, 0xb9, 0x00}}, + {2, [3]byte{0xc3, 0xba, 0x00}}, {2, [3]byte{0xc3, 0xbb, 0x00}}, + {2, [3]byte{0xc3, 0xbc, 0x00}}, {2, [3]byte{0xc4, 0xb1, 0x00}}, + {2, [3]byte{0xc5, 0x9f, 0x00}}, {2, [3]byte{0xc3, 0xbf, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xa00000a0, 0xa10000a1, 0xa20000a2, 0xa30000a3, 0xa40000a4, 0xa50000a5, 0xa60000a6, 0xa70000a7, + 0xa80000a8, 0xa90000a9, 0xaa0000aa, 0xab0000ab, 0xac0000ac, 0xad0000ad, 0xae0000ae, 0xaf0000af, + 0xb00000b0, 0xb10000b1, 0xb20000b2, 0xb30000b3, 0xb40000b4, 0xb50000b5, 0xb60000b6, 0xb70000b7, + 0xb80000b8, 0xb90000b9, 0xba0000ba, 0xbb0000bb, 0xbc0000bc, 0xbd0000bd, 0xbe0000be, 0xbf0000bf, + 0xc00000c0, 0xc10000c1, 0xc20000c2, 0xc30000c3, 0xc40000c4, 0xc50000c5, 0xc60000c6, 0xc70000c7, + 0xc80000c8, 0xc90000c9, 0xca0000ca, 0xcb0000cb, 0xcc0000cc, 0xcd0000cd, 0xce0000ce, 0xcf0000cf, + 0xd10000d1, 0xd20000d2, 0xd30000d3, 0xd40000d4, 0xd50000d5, 0xd60000d6, 0xd70000d7, 0xd80000d8, + 0xd90000d9, 0xda0000da, 0xdb0000db, 0xdc0000dc, 0xdf0000df, 0xe00000e0, 0xe10000e1, 0xe20000e2, + 0xe30000e3, 0xe40000e4, 0xe50000e5, 0xe60000e6, 0xe70000e7, 0xe80000e8, 0xe90000e9, 0xea0000ea, + 0xeb0000eb, 0xec0000ec, 0xed0000ed, 0xee0000ee, 0xef0000ef, 0xf10000f1, 0xf20000f2, 0xf30000f3, + 0xf40000f4, 0xf50000f5, 0xf60000f6, 0xf70000f7, 0xf80000f8, 0xf90000f9, 0xfa0000fa, 0xfb0000fb, + 0xfc0000fc, 0xff0000ff, 0xd000011e, 0xf000011f, 0xdd000130, 0xfd000131, 0x8c000152, 0x9c000153, + 0xde00015e, 0xfe00015f, 0x8a000160, 0x9a000161, 0x9f000178, 0x83000192, 0x880002c6, 0x980002dc, + 0x96002013, 0x97002014, 0x91002018, 0x92002019, 0x8200201a, 0x9300201c, 0x9400201d, 0x8400201e, + 0x86002020, 0x87002021, 0x95002022, 0x85002026, 0x89002030, 0x8b002039, 0x9b00203a, 0x800020ac, + 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, + }, +} + +// Windows1255 is the Windows 1255 encoding. +var Windows1255 *Charmap = &windows1255 + +var windows1255 = Charmap{ + name: "Windows 1255", + mib: identifier.Windows1255, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {3, [3]byte{0xe2, 0x82, 0xac}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xe2, 0x80, 0x9a}}, {2, [3]byte{0xc6, 0x92, 0x00}}, + {3, [3]byte{0xe2, 0x80, 0x9e}}, {3, [3]byte{0xe2, 0x80, 0xa6}}, + {3, [3]byte{0xe2, 0x80, 0xa0}}, {3, [3]byte{0xe2, 0x80, 0xa1}}, + {2, [3]byte{0xcb, 0x86, 0x00}}, {3, [3]byte{0xe2, 0x80, 0xb0}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xe2, 0x80, 0xb9}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xe2, 0x80, 0x98}}, + {3, [3]byte{0xe2, 0x80, 0x99}}, {3, [3]byte{0xe2, 0x80, 0x9c}}, + {3, [3]byte{0xe2, 0x80, 0x9d}}, {3, [3]byte{0xe2, 0x80, 0xa2}}, + {3, [3]byte{0xe2, 0x80, 0x93}}, {3, [3]byte{0xe2, 0x80, 0x94}}, + {2, [3]byte{0xcb, 0x9c, 0x00}}, {3, [3]byte{0xe2, 0x84, 0xa2}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xe2, 0x80, 0xba}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {2, [3]byte{0xc2, 0xa0, 0x00}}, {2, [3]byte{0xc2, 0xa1, 0x00}}, + {2, [3]byte{0xc2, 0xa2, 0x00}}, {2, [3]byte{0xc2, 0xa3, 0x00}}, + {3, [3]byte{0xe2, 0x82, 0xaa}}, {2, [3]byte{0xc2, 0xa5, 0x00}}, + {2, [3]byte{0xc2, 0xa6, 0x00}}, {2, [3]byte{0xc2, 0xa7, 0x00}}, + {2, [3]byte{0xc2, 0xa8, 0x00}}, {2, [3]byte{0xc2, 0xa9, 0x00}}, + {2, [3]byte{0xc3, 0x97, 0x00}}, {2, [3]byte{0xc2, 0xab, 0x00}}, + {2, [3]byte{0xc2, 0xac, 0x00}}, {2, [3]byte{0xc2, 0xad, 0x00}}, + {2, [3]byte{0xc2, 0xae, 0x00}}, {2, [3]byte{0xc2, 0xaf, 0x00}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {2, [3]byte{0xc2, 0xb1, 0x00}}, + {2, [3]byte{0xc2, 0xb2, 0x00}}, {2, [3]byte{0xc2, 0xb3, 0x00}}, + {2, [3]byte{0xc2, 0xb4, 0x00}}, {2, [3]byte{0xc2, 0xb5, 0x00}}, + {2, [3]byte{0xc2, 0xb6, 0x00}}, {2, [3]byte{0xc2, 0xb7, 0x00}}, + {2, [3]byte{0xc2, 0xb8, 0x00}}, {2, [3]byte{0xc2, 0xb9, 0x00}}, + {2, [3]byte{0xc3, 0xb7, 0x00}}, {2, [3]byte{0xc2, 0xbb, 0x00}}, + {2, [3]byte{0xc2, 0xbc, 0x00}}, {2, [3]byte{0xc2, 0xbd, 0x00}}, + {2, [3]byte{0xc2, 0xbe, 0x00}}, {2, [3]byte{0xc2, 0xbf, 0x00}}, + {2, [3]byte{0xd6, 0xb0, 0x00}}, {2, [3]byte{0xd6, 0xb1, 0x00}}, + {2, [3]byte{0xd6, 0xb2, 0x00}}, {2, [3]byte{0xd6, 0xb3, 0x00}}, + {2, [3]byte{0xd6, 0xb4, 0x00}}, {2, [3]byte{0xd6, 0xb5, 0x00}}, + {2, [3]byte{0xd6, 0xb6, 0x00}}, {2, [3]byte{0xd6, 0xb7, 0x00}}, + {2, [3]byte{0xd6, 0xb8, 0x00}}, {2, [3]byte{0xd6, 0xb9, 0x00}}, + {2, [3]byte{0xd6, 0xba, 0x00}}, {2, [3]byte{0xd6, 0xbb, 0x00}}, + {2, [3]byte{0xd6, 0xbc, 0x00}}, {2, [3]byte{0xd6, 0xbd, 0x00}}, + {2, [3]byte{0xd6, 0xbe, 0x00}}, {2, [3]byte{0xd6, 0xbf, 0x00}}, + {2, [3]byte{0xd7, 0x80, 0x00}}, {2, [3]byte{0xd7, 0x81, 0x00}}, + {2, [3]byte{0xd7, 0x82, 0x00}}, {2, [3]byte{0xd7, 0x83, 0x00}}, + {2, [3]byte{0xd7, 0xb0, 0x00}}, {2, [3]byte{0xd7, 0xb1, 0x00}}, + {2, [3]byte{0xd7, 0xb2, 0x00}}, {2, [3]byte{0xd7, 0xb3, 0x00}}, + {2, [3]byte{0xd7, 0xb4, 0x00}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {2, [3]byte{0xd7, 0x90, 0x00}}, {2, [3]byte{0xd7, 0x91, 0x00}}, + {2, [3]byte{0xd7, 0x92, 0x00}}, {2, [3]byte{0xd7, 0x93, 0x00}}, + {2, [3]byte{0xd7, 0x94, 0x00}}, {2, [3]byte{0xd7, 0x95, 0x00}}, + {2, [3]byte{0xd7, 0x96, 0x00}}, {2, [3]byte{0xd7, 0x97, 0x00}}, + {2, [3]byte{0xd7, 0x98, 0x00}}, {2, [3]byte{0xd7, 0x99, 0x00}}, + {2, [3]byte{0xd7, 0x9a, 0x00}}, {2, [3]byte{0xd7, 0x9b, 0x00}}, + {2, [3]byte{0xd7, 0x9c, 0x00}}, {2, [3]byte{0xd7, 0x9d, 0x00}}, + {2, [3]byte{0xd7, 0x9e, 0x00}}, {2, [3]byte{0xd7, 0x9f, 0x00}}, + {2, [3]byte{0xd7, 0xa0, 0x00}}, {2, [3]byte{0xd7, 0xa1, 0x00}}, + {2, [3]byte{0xd7, 0xa2, 0x00}}, {2, [3]byte{0xd7, 0xa3, 0x00}}, + {2, [3]byte{0xd7, 0xa4, 0x00}}, {2, [3]byte{0xd7, 0xa5, 0x00}}, + {2, [3]byte{0xd7, 0xa6, 0x00}}, {2, [3]byte{0xd7, 0xa7, 0x00}}, + {2, [3]byte{0xd7, 0xa8, 0x00}}, {2, [3]byte{0xd7, 0xa9, 0x00}}, + {2, [3]byte{0xd7, 0xaa, 0x00}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xe2, 0x80, 0x8e}}, + {3, [3]byte{0xe2, 0x80, 0x8f}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xa00000a0, 0xa10000a1, 0xa20000a2, 0xa30000a3, 0xa50000a5, 0xa60000a6, 0xa70000a7, 0xa80000a8, + 0xa90000a9, 0xab0000ab, 0xac0000ac, 0xad0000ad, 0xae0000ae, 0xaf0000af, 0xb00000b0, 0xb10000b1, + 0xb20000b2, 0xb30000b3, 0xb40000b4, 0xb50000b5, 0xb60000b6, 0xb70000b7, 0xb80000b8, 0xb90000b9, + 0xbb0000bb, 0xbc0000bc, 0xbd0000bd, 0xbe0000be, 0xbf0000bf, 0xaa0000d7, 0xba0000f7, 0x83000192, + 0x880002c6, 0x980002dc, 0xc00005b0, 0xc10005b1, 0xc20005b2, 0xc30005b3, 0xc40005b4, 0xc50005b5, + 0xc60005b6, 0xc70005b7, 0xc80005b8, 0xc90005b9, 0xca0005ba, 0xcb0005bb, 0xcc0005bc, 0xcd0005bd, + 0xce0005be, 0xcf0005bf, 0xd00005c0, 0xd10005c1, 0xd20005c2, 0xd30005c3, 0xe00005d0, 0xe10005d1, + 0xe20005d2, 0xe30005d3, 0xe40005d4, 0xe50005d5, 0xe60005d6, 0xe70005d7, 0xe80005d8, 0xe90005d9, + 0xea0005da, 0xeb0005db, 0xec0005dc, 0xed0005dd, 0xee0005de, 0xef0005df, 0xf00005e0, 0xf10005e1, + 0xf20005e2, 0xf30005e3, 0xf40005e4, 0xf50005e5, 0xf60005e6, 0xf70005e7, 0xf80005e8, 0xf90005e9, + 0xfa0005ea, 0xd40005f0, 0xd50005f1, 0xd60005f2, 0xd70005f3, 0xd80005f4, 0xfd00200e, 0xfe00200f, + 0x96002013, 0x97002014, 0x91002018, 0x92002019, 0x8200201a, 0x9300201c, 0x9400201d, 0x8400201e, + 0x86002020, 0x87002021, 0x95002022, 0x85002026, 0x89002030, 0x8b002039, 0x9b00203a, 0xa40020aa, + 0x800020ac, 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, + 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, + 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, + }, +} + +// Windows1256 is the Windows 1256 encoding. +var Windows1256 *Charmap = &windows1256 + +var windows1256 = Charmap{ + name: "Windows 1256", + mib: identifier.Windows1256, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {3, [3]byte{0xe2, 0x82, 0xac}}, {2, [3]byte{0xd9, 0xbe, 0x00}}, + {3, [3]byte{0xe2, 0x80, 0x9a}}, {2, [3]byte{0xc6, 0x92, 0x00}}, + {3, [3]byte{0xe2, 0x80, 0x9e}}, {3, [3]byte{0xe2, 0x80, 0xa6}}, + {3, [3]byte{0xe2, 0x80, 0xa0}}, {3, [3]byte{0xe2, 0x80, 0xa1}}, + {2, [3]byte{0xcb, 0x86, 0x00}}, {3, [3]byte{0xe2, 0x80, 0xb0}}, + {2, [3]byte{0xd9, 0xb9, 0x00}}, {3, [3]byte{0xe2, 0x80, 0xb9}}, + {2, [3]byte{0xc5, 0x92, 0x00}}, {2, [3]byte{0xda, 0x86, 0x00}}, + {2, [3]byte{0xda, 0x98, 0x00}}, {2, [3]byte{0xda, 0x88, 0x00}}, + {2, [3]byte{0xda, 0xaf, 0x00}}, {3, [3]byte{0xe2, 0x80, 0x98}}, + {3, [3]byte{0xe2, 0x80, 0x99}}, {3, [3]byte{0xe2, 0x80, 0x9c}}, + {3, [3]byte{0xe2, 0x80, 0x9d}}, {3, [3]byte{0xe2, 0x80, 0xa2}}, + {3, [3]byte{0xe2, 0x80, 0x93}}, {3, [3]byte{0xe2, 0x80, 0x94}}, + {2, [3]byte{0xda, 0xa9, 0x00}}, {3, [3]byte{0xe2, 0x84, 0xa2}}, + {2, [3]byte{0xda, 0x91, 0x00}}, {3, [3]byte{0xe2, 0x80, 0xba}}, + {2, [3]byte{0xc5, 0x93, 0x00}}, {3, [3]byte{0xe2, 0x80, 0x8c}}, + {3, [3]byte{0xe2, 0x80, 0x8d}}, {2, [3]byte{0xda, 0xba, 0x00}}, + {2, [3]byte{0xc2, 0xa0, 0x00}}, {2, [3]byte{0xd8, 0x8c, 0x00}}, + {2, [3]byte{0xc2, 0xa2, 0x00}}, {2, [3]byte{0xc2, 0xa3, 0x00}}, + {2, [3]byte{0xc2, 0xa4, 0x00}}, {2, [3]byte{0xc2, 0xa5, 0x00}}, + {2, [3]byte{0xc2, 0xa6, 0x00}}, {2, [3]byte{0xc2, 0xa7, 0x00}}, + {2, [3]byte{0xc2, 0xa8, 0x00}}, {2, [3]byte{0xc2, 0xa9, 0x00}}, + {2, [3]byte{0xda, 0xbe, 0x00}}, {2, [3]byte{0xc2, 0xab, 0x00}}, + {2, [3]byte{0xc2, 0xac, 0x00}}, {2, [3]byte{0xc2, 0xad, 0x00}}, + {2, [3]byte{0xc2, 0xae, 0x00}}, {2, [3]byte{0xc2, 0xaf, 0x00}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {2, [3]byte{0xc2, 0xb1, 0x00}}, + {2, [3]byte{0xc2, 0xb2, 0x00}}, {2, [3]byte{0xc2, 0xb3, 0x00}}, + {2, [3]byte{0xc2, 0xb4, 0x00}}, {2, [3]byte{0xc2, 0xb5, 0x00}}, + {2, [3]byte{0xc2, 0xb6, 0x00}}, {2, [3]byte{0xc2, 0xb7, 0x00}}, + {2, [3]byte{0xc2, 0xb8, 0x00}}, {2, [3]byte{0xc2, 0xb9, 0x00}}, + {2, [3]byte{0xd8, 0x9b, 0x00}}, {2, [3]byte{0xc2, 0xbb, 0x00}}, + {2, [3]byte{0xc2, 0xbc, 0x00}}, {2, [3]byte{0xc2, 0xbd, 0x00}}, + {2, [3]byte{0xc2, 0xbe, 0x00}}, {2, [3]byte{0xd8, 0x9f, 0x00}}, + {2, [3]byte{0xdb, 0x81, 0x00}}, {2, [3]byte{0xd8, 0xa1, 0x00}}, + {2, [3]byte{0xd8, 0xa2, 0x00}}, {2, [3]byte{0xd8, 0xa3, 0x00}}, + {2, [3]byte{0xd8, 0xa4, 0x00}}, {2, [3]byte{0xd8, 0xa5, 0x00}}, + {2, [3]byte{0xd8, 0xa6, 0x00}}, {2, [3]byte{0xd8, 0xa7, 0x00}}, + {2, [3]byte{0xd8, 0xa8, 0x00}}, {2, [3]byte{0xd8, 0xa9, 0x00}}, + {2, [3]byte{0xd8, 0xaa, 0x00}}, {2, [3]byte{0xd8, 0xab, 0x00}}, + {2, [3]byte{0xd8, 0xac, 0x00}}, {2, [3]byte{0xd8, 0xad, 0x00}}, + {2, [3]byte{0xd8, 0xae, 0x00}}, {2, [3]byte{0xd8, 0xaf, 0x00}}, + {2, [3]byte{0xd8, 0xb0, 0x00}}, {2, [3]byte{0xd8, 0xb1, 0x00}}, + {2, [3]byte{0xd8, 0xb2, 0x00}}, {2, [3]byte{0xd8, 0xb3, 0x00}}, + {2, [3]byte{0xd8, 0xb4, 0x00}}, {2, [3]byte{0xd8, 0xb5, 0x00}}, + {2, [3]byte{0xd8, 0xb6, 0x00}}, {2, [3]byte{0xc3, 0x97, 0x00}}, + {2, [3]byte{0xd8, 0xb7, 0x00}}, {2, [3]byte{0xd8, 0xb8, 0x00}}, + {2, [3]byte{0xd8, 0xb9, 0x00}}, {2, [3]byte{0xd8, 0xba, 0x00}}, + {2, [3]byte{0xd9, 0x80, 0x00}}, {2, [3]byte{0xd9, 0x81, 0x00}}, + {2, [3]byte{0xd9, 0x82, 0x00}}, {2, [3]byte{0xd9, 0x83, 0x00}}, + {2, [3]byte{0xc3, 0xa0, 0x00}}, {2, [3]byte{0xd9, 0x84, 0x00}}, + {2, [3]byte{0xc3, 0xa2, 0x00}}, {2, [3]byte{0xd9, 0x85, 0x00}}, + {2, [3]byte{0xd9, 0x86, 0x00}}, {2, [3]byte{0xd9, 0x87, 0x00}}, + {2, [3]byte{0xd9, 0x88, 0x00}}, {2, [3]byte{0xc3, 0xa7, 0x00}}, + {2, [3]byte{0xc3, 0xa8, 0x00}}, {2, [3]byte{0xc3, 0xa9, 0x00}}, + {2, [3]byte{0xc3, 0xaa, 0x00}}, {2, [3]byte{0xc3, 0xab, 0x00}}, + {2, [3]byte{0xd9, 0x89, 0x00}}, {2, [3]byte{0xd9, 0x8a, 0x00}}, + {2, [3]byte{0xc3, 0xae, 0x00}}, {2, [3]byte{0xc3, 0xaf, 0x00}}, + {2, [3]byte{0xd9, 0x8b, 0x00}}, {2, [3]byte{0xd9, 0x8c, 0x00}}, + {2, [3]byte{0xd9, 0x8d, 0x00}}, {2, [3]byte{0xd9, 0x8e, 0x00}}, + {2, [3]byte{0xc3, 0xb4, 0x00}}, {2, [3]byte{0xd9, 0x8f, 0x00}}, + {2, [3]byte{0xd9, 0x90, 0x00}}, {2, [3]byte{0xc3, 0xb7, 0x00}}, + {2, [3]byte{0xd9, 0x91, 0x00}}, {2, [3]byte{0xc3, 0xb9, 0x00}}, + {2, [3]byte{0xd9, 0x92, 0x00}}, {2, [3]byte{0xc3, 0xbb, 0x00}}, + {2, [3]byte{0xc3, 0xbc, 0x00}}, {3, [3]byte{0xe2, 0x80, 0x8e}}, + {3, [3]byte{0xe2, 0x80, 0x8f}}, {2, [3]byte{0xdb, 0x92, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xa00000a0, 0xa20000a2, 0xa30000a3, 0xa40000a4, 0xa50000a5, 0xa60000a6, 0xa70000a7, 0xa80000a8, + 0xa90000a9, 0xab0000ab, 0xac0000ac, 0xad0000ad, 0xae0000ae, 0xaf0000af, 0xb00000b0, 0xb10000b1, + 0xb20000b2, 0xb30000b3, 0xb40000b4, 0xb50000b5, 0xb60000b6, 0xb70000b7, 0xb80000b8, 0xb90000b9, + 0xbb0000bb, 0xbc0000bc, 0xbd0000bd, 0xbe0000be, 0xd70000d7, 0xe00000e0, 0xe20000e2, 0xe70000e7, + 0xe80000e8, 0xe90000e9, 0xea0000ea, 0xeb0000eb, 0xee0000ee, 0xef0000ef, 0xf40000f4, 0xf70000f7, + 0xf90000f9, 0xfb0000fb, 0xfc0000fc, 0x8c000152, 0x9c000153, 0x83000192, 0x880002c6, 0xa100060c, + 0xba00061b, 0xbf00061f, 0xc1000621, 0xc2000622, 0xc3000623, 0xc4000624, 0xc5000625, 0xc6000626, + 0xc7000627, 0xc8000628, 0xc9000629, 0xca00062a, 0xcb00062b, 0xcc00062c, 0xcd00062d, 0xce00062e, + 0xcf00062f, 0xd0000630, 0xd1000631, 0xd2000632, 0xd3000633, 0xd4000634, 0xd5000635, 0xd6000636, + 0xd8000637, 0xd9000638, 0xda000639, 0xdb00063a, 0xdc000640, 0xdd000641, 0xde000642, 0xdf000643, + 0xe1000644, 0xe3000645, 0xe4000646, 0xe5000647, 0xe6000648, 0xec000649, 0xed00064a, 0xf000064b, + 0xf100064c, 0xf200064d, 0xf300064e, 0xf500064f, 0xf6000650, 0xf8000651, 0xfa000652, 0x8a000679, + 0x8100067e, 0x8d000686, 0x8f000688, 0x9a000691, 0x8e000698, 0x980006a9, 0x900006af, 0x9f0006ba, + 0xaa0006be, 0xc00006c1, 0xff0006d2, 0x9d00200c, 0x9e00200d, 0xfd00200e, 0xfe00200f, 0x96002013, + 0x97002014, 0x91002018, 0x92002019, 0x8200201a, 0x9300201c, 0x9400201d, 0x8400201e, 0x86002020, + 0x87002021, 0x95002022, 0x85002026, 0x89002030, 0x8b002039, 0x9b00203a, 0x800020ac, 0x99002122, + }, +} + +// Windows1257 is the Windows 1257 encoding. +var Windows1257 *Charmap = &windows1257 + +var windows1257 = Charmap{ + name: "Windows 1257", + mib: identifier.Windows1257, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {3, [3]byte{0xe2, 0x82, 0xac}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xe2, 0x80, 0x9a}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xe2, 0x80, 0x9e}}, {3, [3]byte{0xe2, 0x80, 0xa6}}, + {3, [3]byte{0xe2, 0x80, 0xa0}}, {3, [3]byte{0xe2, 0x80, 0xa1}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xe2, 0x80, 0xb0}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xe2, 0x80, 0xb9}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {2, [3]byte{0xc2, 0xa8, 0x00}}, + {2, [3]byte{0xcb, 0x87, 0x00}}, {2, [3]byte{0xc2, 0xb8, 0x00}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xe2, 0x80, 0x98}}, + {3, [3]byte{0xe2, 0x80, 0x99}}, {3, [3]byte{0xe2, 0x80, 0x9c}}, + {3, [3]byte{0xe2, 0x80, 0x9d}}, {3, [3]byte{0xe2, 0x80, 0xa2}}, + {3, [3]byte{0xe2, 0x80, 0x93}}, {3, [3]byte{0xe2, 0x80, 0x94}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xe2, 0x84, 0xa2}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xe2, 0x80, 0xba}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {2, [3]byte{0xc2, 0xaf, 0x00}}, + {2, [3]byte{0xcb, 0x9b, 0x00}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {2, [3]byte{0xc2, 0xa0, 0x00}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {2, [3]byte{0xc2, 0xa2, 0x00}}, {2, [3]byte{0xc2, 0xa3, 0x00}}, + {2, [3]byte{0xc2, 0xa4, 0x00}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {2, [3]byte{0xc2, 0xa6, 0x00}}, {2, [3]byte{0xc2, 0xa7, 0x00}}, + {2, [3]byte{0xc3, 0x98, 0x00}}, {2, [3]byte{0xc2, 0xa9, 0x00}}, + {2, [3]byte{0xc5, 0x96, 0x00}}, {2, [3]byte{0xc2, 0xab, 0x00}}, + {2, [3]byte{0xc2, 0xac, 0x00}}, {2, [3]byte{0xc2, 0xad, 0x00}}, + {2, [3]byte{0xc2, 0xae, 0x00}}, {2, [3]byte{0xc3, 0x86, 0x00}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {2, [3]byte{0xc2, 0xb1, 0x00}}, + {2, [3]byte{0xc2, 0xb2, 0x00}}, {2, [3]byte{0xc2, 0xb3, 0x00}}, + {2, [3]byte{0xc2, 0xb4, 0x00}}, {2, [3]byte{0xc2, 0xb5, 0x00}}, + {2, [3]byte{0xc2, 0xb6, 0x00}}, {2, [3]byte{0xc2, 0xb7, 0x00}}, + {2, [3]byte{0xc3, 0xb8, 0x00}}, {2, [3]byte{0xc2, 0xb9, 0x00}}, + {2, [3]byte{0xc5, 0x97, 0x00}}, {2, [3]byte{0xc2, 0xbb, 0x00}}, + {2, [3]byte{0xc2, 0xbc, 0x00}}, {2, [3]byte{0xc2, 0xbd, 0x00}}, + {2, [3]byte{0xc2, 0xbe, 0x00}}, {2, [3]byte{0xc3, 0xa6, 0x00}}, + {2, [3]byte{0xc4, 0x84, 0x00}}, {2, [3]byte{0xc4, 0xae, 0x00}}, + {2, [3]byte{0xc4, 0x80, 0x00}}, {2, [3]byte{0xc4, 0x86, 0x00}}, + {2, [3]byte{0xc3, 0x84, 0x00}}, {2, [3]byte{0xc3, 0x85, 0x00}}, + {2, [3]byte{0xc4, 0x98, 0x00}}, {2, [3]byte{0xc4, 0x92, 0x00}}, + {2, [3]byte{0xc4, 0x8c, 0x00}}, {2, [3]byte{0xc3, 0x89, 0x00}}, + {2, [3]byte{0xc5, 0xb9, 0x00}}, {2, [3]byte{0xc4, 0x96, 0x00}}, + {2, [3]byte{0xc4, 0xa2, 0x00}}, {2, [3]byte{0xc4, 0xb6, 0x00}}, + {2, [3]byte{0xc4, 0xaa, 0x00}}, {2, [3]byte{0xc4, 0xbb, 0x00}}, + {2, [3]byte{0xc5, 0xa0, 0x00}}, {2, [3]byte{0xc5, 0x83, 0x00}}, + {2, [3]byte{0xc5, 0x85, 0x00}}, {2, [3]byte{0xc3, 0x93, 0x00}}, + {2, [3]byte{0xc5, 0x8c, 0x00}}, {2, [3]byte{0xc3, 0x95, 0x00}}, + {2, [3]byte{0xc3, 0x96, 0x00}}, {2, [3]byte{0xc3, 0x97, 0x00}}, + {2, [3]byte{0xc5, 0xb2, 0x00}}, {2, [3]byte{0xc5, 0x81, 0x00}}, + {2, [3]byte{0xc5, 0x9a, 0x00}}, {2, [3]byte{0xc5, 0xaa, 0x00}}, + {2, [3]byte{0xc3, 0x9c, 0x00}}, {2, [3]byte{0xc5, 0xbb, 0x00}}, + {2, [3]byte{0xc5, 0xbd, 0x00}}, {2, [3]byte{0xc3, 0x9f, 0x00}}, + {2, [3]byte{0xc4, 0x85, 0x00}}, {2, [3]byte{0xc4, 0xaf, 0x00}}, + {2, [3]byte{0xc4, 0x81, 0x00}}, {2, [3]byte{0xc4, 0x87, 0x00}}, + {2, [3]byte{0xc3, 0xa4, 0x00}}, {2, [3]byte{0xc3, 0xa5, 0x00}}, + {2, [3]byte{0xc4, 0x99, 0x00}}, {2, [3]byte{0xc4, 0x93, 0x00}}, + {2, [3]byte{0xc4, 0x8d, 0x00}}, {2, [3]byte{0xc3, 0xa9, 0x00}}, + {2, [3]byte{0xc5, 0xba, 0x00}}, {2, [3]byte{0xc4, 0x97, 0x00}}, + {2, [3]byte{0xc4, 0xa3, 0x00}}, {2, [3]byte{0xc4, 0xb7, 0x00}}, + {2, [3]byte{0xc4, 0xab, 0x00}}, {2, [3]byte{0xc4, 0xbc, 0x00}}, + {2, [3]byte{0xc5, 0xa1, 0x00}}, {2, [3]byte{0xc5, 0x84, 0x00}}, + {2, [3]byte{0xc5, 0x86, 0x00}}, {2, [3]byte{0xc3, 0xb3, 0x00}}, + {2, [3]byte{0xc5, 0x8d, 0x00}}, {2, [3]byte{0xc3, 0xb5, 0x00}}, + {2, [3]byte{0xc3, 0xb6, 0x00}}, {2, [3]byte{0xc3, 0xb7, 0x00}}, + {2, [3]byte{0xc5, 0xb3, 0x00}}, {2, [3]byte{0xc5, 0x82, 0x00}}, + {2, [3]byte{0xc5, 0x9b, 0x00}}, {2, [3]byte{0xc5, 0xab, 0x00}}, + {2, [3]byte{0xc3, 0xbc, 0x00}}, {2, [3]byte{0xc5, 0xbc, 0x00}}, + {2, [3]byte{0xc5, 0xbe, 0x00}}, {2, [3]byte{0xcb, 0x99, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xa00000a0, 0xa20000a2, 0xa30000a3, 0xa40000a4, 0xa60000a6, 0xa70000a7, 0x8d0000a8, 0xa90000a9, + 0xab0000ab, 0xac0000ac, 0xad0000ad, 0xae0000ae, 0x9d0000af, 0xb00000b0, 0xb10000b1, 0xb20000b2, + 0xb30000b3, 0xb40000b4, 0xb50000b5, 0xb60000b6, 0xb70000b7, 0x8f0000b8, 0xb90000b9, 0xbb0000bb, + 0xbc0000bc, 0xbd0000bd, 0xbe0000be, 0xc40000c4, 0xc50000c5, 0xaf0000c6, 0xc90000c9, 0xd30000d3, + 0xd50000d5, 0xd60000d6, 0xd70000d7, 0xa80000d8, 0xdc0000dc, 0xdf0000df, 0xe40000e4, 0xe50000e5, + 0xbf0000e6, 0xe90000e9, 0xf30000f3, 0xf50000f5, 0xf60000f6, 0xf70000f7, 0xb80000f8, 0xfc0000fc, + 0xc2000100, 0xe2000101, 0xc0000104, 0xe0000105, 0xc3000106, 0xe3000107, 0xc800010c, 0xe800010d, + 0xc7000112, 0xe7000113, 0xcb000116, 0xeb000117, 0xc6000118, 0xe6000119, 0xcc000122, 0xec000123, + 0xce00012a, 0xee00012b, 0xc100012e, 0xe100012f, 0xcd000136, 0xed000137, 0xcf00013b, 0xef00013c, + 0xd9000141, 0xf9000142, 0xd1000143, 0xf1000144, 0xd2000145, 0xf2000146, 0xd400014c, 0xf400014d, + 0xaa000156, 0xba000157, 0xda00015a, 0xfa00015b, 0xd0000160, 0xf0000161, 0xdb00016a, 0xfb00016b, + 0xd8000172, 0xf8000173, 0xca000179, 0xea00017a, 0xdd00017b, 0xfd00017c, 0xde00017d, 0xfe00017e, + 0x8e0002c7, 0xff0002d9, 0x9e0002db, 0x96002013, 0x97002014, 0x91002018, 0x92002019, 0x8200201a, + 0x9300201c, 0x9400201d, 0x8400201e, 0x86002020, 0x87002021, 0x95002022, 0x85002026, 0x89002030, + 0x8b002039, 0x9b00203a, 0x800020ac, 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, + 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, + }, +} + +// Windows1258 is the Windows 1258 encoding. +var Windows1258 *Charmap = &windows1258 + +var windows1258 = Charmap{ + name: "Windows 1258", + mib: identifier.Windows1258, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {3, [3]byte{0xe2, 0x82, 0xac}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xe2, 0x80, 0x9a}}, {2, [3]byte{0xc6, 0x92, 0x00}}, + {3, [3]byte{0xe2, 0x80, 0x9e}}, {3, [3]byte{0xe2, 0x80, 0xa6}}, + {3, [3]byte{0xe2, 0x80, 0xa0}}, {3, [3]byte{0xe2, 0x80, 0xa1}}, + {2, [3]byte{0xcb, 0x86, 0x00}}, {3, [3]byte{0xe2, 0x80, 0xb0}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xe2, 0x80, 0xb9}}, + {2, [3]byte{0xc5, 0x92, 0x00}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xe2, 0x80, 0x98}}, + {3, [3]byte{0xe2, 0x80, 0x99}}, {3, [3]byte{0xe2, 0x80, 0x9c}}, + {3, [3]byte{0xe2, 0x80, 0x9d}}, {3, [3]byte{0xe2, 0x80, 0xa2}}, + {3, [3]byte{0xe2, 0x80, 0x93}}, {3, [3]byte{0xe2, 0x80, 0x94}}, + {2, [3]byte{0xcb, 0x9c, 0x00}}, {3, [3]byte{0xe2, 0x84, 0xa2}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {3, [3]byte{0xe2, 0x80, 0xba}}, + {2, [3]byte{0xc5, 0x93, 0x00}}, {3, [3]byte{0xef, 0xbf, 0xbd}}, + {3, [3]byte{0xef, 0xbf, 0xbd}}, {2, [3]byte{0xc5, 0xb8, 0x00}}, + {2, [3]byte{0xc2, 0xa0, 0x00}}, {2, [3]byte{0xc2, 0xa1, 0x00}}, + {2, [3]byte{0xc2, 0xa2, 0x00}}, {2, [3]byte{0xc2, 0xa3, 0x00}}, + {2, [3]byte{0xc2, 0xa4, 0x00}}, {2, [3]byte{0xc2, 0xa5, 0x00}}, + {2, [3]byte{0xc2, 0xa6, 0x00}}, {2, [3]byte{0xc2, 0xa7, 0x00}}, + {2, [3]byte{0xc2, 0xa8, 0x00}}, {2, [3]byte{0xc2, 0xa9, 0x00}}, + {2, [3]byte{0xc2, 0xaa, 0x00}}, {2, [3]byte{0xc2, 0xab, 0x00}}, + {2, [3]byte{0xc2, 0xac, 0x00}}, {2, [3]byte{0xc2, 0xad, 0x00}}, + {2, [3]byte{0xc2, 0xae, 0x00}}, {2, [3]byte{0xc2, 0xaf, 0x00}}, + {2, [3]byte{0xc2, 0xb0, 0x00}}, {2, [3]byte{0xc2, 0xb1, 0x00}}, + {2, [3]byte{0xc2, 0xb2, 0x00}}, {2, [3]byte{0xc2, 0xb3, 0x00}}, + {2, [3]byte{0xc2, 0xb4, 0x00}}, {2, [3]byte{0xc2, 0xb5, 0x00}}, + {2, [3]byte{0xc2, 0xb6, 0x00}}, {2, [3]byte{0xc2, 0xb7, 0x00}}, + {2, [3]byte{0xc2, 0xb8, 0x00}}, {2, [3]byte{0xc2, 0xb9, 0x00}}, + {2, [3]byte{0xc2, 0xba, 0x00}}, {2, [3]byte{0xc2, 0xbb, 0x00}}, + {2, [3]byte{0xc2, 0xbc, 0x00}}, {2, [3]byte{0xc2, 0xbd, 0x00}}, + {2, [3]byte{0xc2, 0xbe, 0x00}}, {2, [3]byte{0xc2, 0xbf, 0x00}}, + {2, [3]byte{0xc3, 0x80, 0x00}}, {2, [3]byte{0xc3, 0x81, 0x00}}, + {2, [3]byte{0xc3, 0x82, 0x00}}, {2, [3]byte{0xc4, 0x82, 0x00}}, + {2, [3]byte{0xc3, 0x84, 0x00}}, {2, [3]byte{0xc3, 0x85, 0x00}}, + {2, [3]byte{0xc3, 0x86, 0x00}}, {2, [3]byte{0xc3, 0x87, 0x00}}, + {2, [3]byte{0xc3, 0x88, 0x00}}, {2, [3]byte{0xc3, 0x89, 0x00}}, + {2, [3]byte{0xc3, 0x8a, 0x00}}, {2, [3]byte{0xc3, 0x8b, 0x00}}, + {2, [3]byte{0xcc, 0x80, 0x00}}, {2, [3]byte{0xc3, 0x8d, 0x00}}, + {2, [3]byte{0xc3, 0x8e, 0x00}}, {2, [3]byte{0xc3, 0x8f, 0x00}}, + {2, [3]byte{0xc4, 0x90, 0x00}}, {2, [3]byte{0xc3, 0x91, 0x00}}, + {2, [3]byte{0xcc, 0x89, 0x00}}, {2, [3]byte{0xc3, 0x93, 0x00}}, + {2, [3]byte{0xc3, 0x94, 0x00}}, {2, [3]byte{0xc6, 0xa0, 0x00}}, + {2, [3]byte{0xc3, 0x96, 0x00}}, {2, [3]byte{0xc3, 0x97, 0x00}}, + {2, [3]byte{0xc3, 0x98, 0x00}}, {2, [3]byte{0xc3, 0x99, 0x00}}, + {2, [3]byte{0xc3, 0x9a, 0x00}}, {2, [3]byte{0xc3, 0x9b, 0x00}}, + {2, [3]byte{0xc3, 0x9c, 0x00}}, {2, [3]byte{0xc6, 0xaf, 0x00}}, + {2, [3]byte{0xcc, 0x83, 0x00}}, {2, [3]byte{0xc3, 0x9f, 0x00}}, + {2, [3]byte{0xc3, 0xa0, 0x00}}, {2, [3]byte{0xc3, 0xa1, 0x00}}, + {2, [3]byte{0xc3, 0xa2, 0x00}}, {2, [3]byte{0xc4, 0x83, 0x00}}, + {2, [3]byte{0xc3, 0xa4, 0x00}}, {2, [3]byte{0xc3, 0xa5, 0x00}}, + {2, [3]byte{0xc3, 0xa6, 0x00}}, {2, [3]byte{0xc3, 0xa7, 0x00}}, + {2, [3]byte{0xc3, 0xa8, 0x00}}, {2, [3]byte{0xc3, 0xa9, 0x00}}, + {2, [3]byte{0xc3, 0xaa, 0x00}}, {2, [3]byte{0xc3, 0xab, 0x00}}, + {2, [3]byte{0xcc, 0x81, 0x00}}, {2, [3]byte{0xc3, 0xad, 0x00}}, + {2, [3]byte{0xc3, 0xae, 0x00}}, {2, [3]byte{0xc3, 0xaf, 0x00}}, + {2, [3]byte{0xc4, 0x91, 0x00}}, {2, [3]byte{0xc3, 0xb1, 0x00}}, + {2, [3]byte{0xcc, 0xa3, 0x00}}, {2, [3]byte{0xc3, 0xb3, 0x00}}, + {2, [3]byte{0xc3, 0xb4, 0x00}}, {2, [3]byte{0xc6, 0xa1, 0x00}}, + {2, [3]byte{0xc3, 0xb6, 0x00}}, {2, [3]byte{0xc3, 0xb7, 0x00}}, + {2, [3]byte{0xc3, 0xb8, 0x00}}, {2, [3]byte{0xc3, 0xb9, 0x00}}, + {2, [3]byte{0xc3, 0xba, 0x00}}, {2, [3]byte{0xc3, 0xbb, 0x00}}, + {2, [3]byte{0xc3, 0xbc, 0x00}}, {2, [3]byte{0xc6, 0xb0, 0x00}}, + {3, [3]byte{0xe2, 0x82, 0xab}}, {2, [3]byte{0xc3, 0xbf, 0x00}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0xa00000a0, 0xa10000a1, 0xa20000a2, 0xa30000a3, 0xa40000a4, 0xa50000a5, 0xa60000a6, 0xa70000a7, + 0xa80000a8, 0xa90000a9, 0xaa0000aa, 0xab0000ab, 0xac0000ac, 0xad0000ad, 0xae0000ae, 0xaf0000af, + 0xb00000b0, 0xb10000b1, 0xb20000b2, 0xb30000b3, 0xb40000b4, 0xb50000b5, 0xb60000b6, 0xb70000b7, + 0xb80000b8, 0xb90000b9, 0xba0000ba, 0xbb0000bb, 0xbc0000bc, 0xbd0000bd, 0xbe0000be, 0xbf0000bf, + 0xc00000c0, 0xc10000c1, 0xc20000c2, 0xc40000c4, 0xc50000c5, 0xc60000c6, 0xc70000c7, 0xc80000c8, + 0xc90000c9, 0xca0000ca, 0xcb0000cb, 0xcd0000cd, 0xce0000ce, 0xcf0000cf, 0xd10000d1, 0xd30000d3, + 0xd40000d4, 0xd60000d6, 0xd70000d7, 0xd80000d8, 0xd90000d9, 0xda0000da, 0xdb0000db, 0xdc0000dc, + 0xdf0000df, 0xe00000e0, 0xe10000e1, 0xe20000e2, 0xe40000e4, 0xe50000e5, 0xe60000e6, 0xe70000e7, + 0xe80000e8, 0xe90000e9, 0xea0000ea, 0xeb0000eb, 0xed0000ed, 0xee0000ee, 0xef0000ef, 0xf10000f1, + 0xf30000f3, 0xf40000f4, 0xf60000f6, 0xf70000f7, 0xf80000f8, 0xf90000f9, 0xfa0000fa, 0xfb0000fb, + 0xfc0000fc, 0xff0000ff, 0xc3000102, 0xe3000103, 0xd0000110, 0xf0000111, 0x8c000152, 0x9c000153, + 0x9f000178, 0x83000192, 0xd50001a0, 0xf50001a1, 0xdd0001af, 0xfd0001b0, 0x880002c6, 0x980002dc, + 0xcc000300, 0xec000301, 0xde000303, 0xd2000309, 0xf2000323, 0x96002013, 0x97002014, 0x91002018, + 0x92002019, 0x8200201a, 0x9300201c, 0x9400201d, 0x8400201e, 0x86002020, 0x87002021, 0x95002022, + 0x85002026, 0x89002030, 0x8b002039, 0x9b00203a, 0xfe0020ab, 0x800020ac, 0x99002122, 0x99002122, + 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, 0x99002122, + }, +} + +// XUserDefined is the X-User-Defined encoding. +// +// It is defined at http://encoding.spec.whatwg.org/#x-user-defined +var XUserDefined *Charmap = &xUserDefined + +var xUserDefined = Charmap{ + name: "X-User-Defined", + mib: identifier.XUserDefined, + asciiSuperset: true, + low: 0x80, + replacement: 0x1a, + decode: [256]utf8Enc{ + {1, [3]byte{0x00, 0x00, 0x00}}, {1, [3]byte{0x01, 0x00, 0x00}}, + {1, [3]byte{0x02, 0x00, 0x00}}, {1, [3]byte{0x03, 0x00, 0x00}}, + {1, [3]byte{0x04, 0x00, 0x00}}, {1, [3]byte{0x05, 0x00, 0x00}}, + {1, [3]byte{0x06, 0x00, 0x00}}, {1, [3]byte{0x07, 0x00, 0x00}}, + {1, [3]byte{0x08, 0x00, 0x00}}, {1, [3]byte{0x09, 0x00, 0x00}}, + {1, [3]byte{0x0a, 0x00, 0x00}}, {1, [3]byte{0x0b, 0x00, 0x00}}, + {1, [3]byte{0x0c, 0x00, 0x00}}, {1, [3]byte{0x0d, 0x00, 0x00}}, + {1, [3]byte{0x0e, 0x00, 0x00}}, {1, [3]byte{0x0f, 0x00, 0x00}}, + {1, [3]byte{0x10, 0x00, 0x00}}, {1, [3]byte{0x11, 0x00, 0x00}}, + {1, [3]byte{0x12, 0x00, 0x00}}, {1, [3]byte{0x13, 0x00, 0x00}}, + {1, [3]byte{0x14, 0x00, 0x00}}, {1, [3]byte{0x15, 0x00, 0x00}}, + {1, [3]byte{0x16, 0x00, 0x00}}, {1, [3]byte{0x17, 0x00, 0x00}}, + {1, [3]byte{0x18, 0x00, 0x00}}, {1, [3]byte{0x19, 0x00, 0x00}}, + {1, [3]byte{0x1a, 0x00, 0x00}}, {1, [3]byte{0x1b, 0x00, 0x00}}, + {1, [3]byte{0x1c, 0x00, 0x00}}, {1, [3]byte{0x1d, 0x00, 0x00}}, + {1, [3]byte{0x1e, 0x00, 0x00}}, {1, [3]byte{0x1f, 0x00, 0x00}}, + {1, [3]byte{0x20, 0x00, 0x00}}, {1, [3]byte{0x21, 0x00, 0x00}}, + {1, [3]byte{0x22, 0x00, 0x00}}, {1, [3]byte{0x23, 0x00, 0x00}}, + {1, [3]byte{0x24, 0x00, 0x00}}, {1, [3]byte{0x25, 0x00, 0x00}}, + {1, [3]byte{0x26, 0x00, 0x00}}, {1, [3]byte{0x27, 0x00, 0x00}}, + {1, [3]byte{0x28, 0x00, 0x00}}, {1, [3]byte{0x29, 0x00, 0x00}}, + {1, [3]byte{0x2a, 0x00, 0x00}}, {1, [3]byte{0x2b, 0x00, 0x00}}, + {1, [3]byte{0x2c, 0x00, 0x00}}, {1, [3]byte{0x2d, 0x00, 0x00}}, + {1, [3]byte{0x2e, 0x00, 0x00}}, {1, [3]byte{0x2f, 0x00, 0x00}}, + {1, [3]byte{0x30, 0x00, 0x00}}, {1, [3]byte{0x31, 0x00, 0x00}}, + {1, [3]byte{0x32, 0x00, 0x00}}, {1, [3]byte{0x33, 0x00, 0x00}}, + {1, [3]byte{0x34, 0x00, 0x00}}, {1, [3]byte{0x35, 0x00, 0x00}}, + {1, [3]byte{0x36, 0x00, 0x00}}, {1, [3]byte{0x37, 0x00, 0x00}}, + {1, [3]byte{0x38, 0x00, 0x00}}, {1, [3]byte{0x39, 0x00, 0x00}}, + {1, [3]byte{0x3a, 0x00, 0x00}}, {1, [3]byte{0x3b, 0x00, 0x00}}, + {1, [3]byte{0x3c, 0x00, 0x00}}, {1, [3]byte{0x3d, 0x00, 0x00}}, + {1, [3]byte{0x3e, 0x00, 0x00}}, {1, [3]byte{0x3f, 0x00, 0x00}}, + {1, [3]byte{0x40, 0x00, 0x00}}, {1, [3]byte{0x41, 0x00, 0x00}}, + {1, [3]byte{0x42, 0x00, 0x00}}, {1, [3]byte{0x43, 0x00, 0x00}}, + {1, [3]byte{0x44, 0x00, 0x00}}, {1, [3]byte{0x45, 0x00, 0x00}}, + {1, [3]byte{0x46, 0x00, 0x00}}, {1, [3]byte{0x47, 0x00, 0x00}}, + {1, [3]byte{0x48, 0x00, 0x00}}, {1, [3]byte{0x49, 0x00, 0x00}}, + {1, [3]byte{0x4a, 0x00, 0x00}}, {1, [3]byte{0x4b, 0x00, 0x00}}, + {1, [3]byte{0x4c, 0x00, 0x00}}, {1, [3]byte{0x4d, 0x00, 0x00}}, + {1, [3]byte{0x4e, 0x00, 0x00}}, {1, [3]byte{0x4f, 0x00, 0x00}}, + {1, [3]byte{0x50, 0x00, 0x00}}, {1, [3]byte{0x51, 0x00, 0x00}}, + {1, [3]byte{0x52, 0x00, 0x00}}, {1, [3]byte{0x53, 0x00, 0x00}}, + {1, [3]byte{0x54, 0x00, 0x00}}, {1, [3]byte{0x55, 0x00, 0x00}}, + {1, [3]byte{0x56, 0x00, 0x00}}, {1, [3]byte{0x57, 0x00, 0x00}}, + {1, [3]byte{0x58, 0x00, 0x00}}, {1, [3]byte{0x59, 0x00, 0x00}}, + {1, [3]byte{0x5a, 0x00, 0x00}}, {1, [3]byte{0x5b, 0x00, 0x00}}, + {1, [3]byte{0x5c, 0x00, 0x00}}, {1, [3]byte{0x5d, 0x00, 0x00}}, + {1, [3]byte{0x5e, 0x00, 0x00}}, {1, [3]byte{0x5f, 0x00, 0x00}}, + {1, [3]byte{0x60, 0x00, 0x00}}, {1, [3]byte{0x61, 0x00, 0x00}}, + {1, [3]byte{0x62, 0x00, 0x00}}, {1, [3]byte{0x63, 0x00, 0x00}}, + {1, [3]byte{0x64, 0x00, 0x00}}, {1, [3]byte{0x65, 0x00, 0x00}}, + {1, [3]byte{0x66, 0x00, 0x00}}, {1, [3]byte{0x67, 0x00, 0x00}}, + {1, [3]byte{0x68, 0x00, 0x00}}, {1, [3]byte{0x69, 0x00, 0x00}}, + {1, [3]byte{0x6a, 0x00, 0x00}}, {1, [3]byte{0x6b, 0x00, 0x00}}, + {1, [3]byte{0x6c, 0x00, 0x00}}, {1, [3]byte{0x6d, 0x00, 0x00}}, + {1, [3]byte{0x6e, 0x00, 0x00}}, {1, [3]byte{0x6f, 0x00, 0x00}}, + {1, [3]byte{0x70, 0x00, 0x00}}, {1, [3]byte{0x71, 0x00, 0x00}}, + {1, [3]byte{0x72, 0x00, 0x00}}, {1, [3]byte{0x73, 0x00, 0x00}}, + {1, [3]byte{0x74, 0x00, 0x00}}, {1, [3]byte{0x75, 0x00, 0x00}}, + {1, [3]byte{0x76, 0x00, 0x00}}, {1, [3]byte{0x77, 0x00, 0x00}}, + {1, [3]byte{0x78, 0x00, 0x00}}, {1, [3]byte{0x79, 0x00, 0x00}}, + {1, [3]byte{0x7a, 0x00, 0x00}}, {1, [3]byte{0x7b, 0x00, 0x00}}, + {1, [3]byte{0x7c, 0x00, 0x00}}, {1, [3]byte{0x7d, 0x00, 0x00}}, + {1, [3]byte{0x7e, 0x00, 0x00}}, {1, [3]byte{0x7f, 0x00, 0x00}}, + {3, [3]byte{0xef, 0x9e, 0x80}}, {3, [3]byte{0xef, 0x9e, 0x81}}, + {3, [3]byte{0xef, 0x9e, 0x82}}, {3, [3]byte{0xef, 0x9e, 0x83}}, + {3, [3]byte{0xef, 0x9e, 0x84}}, {3, [3]byte{0xef, 0x9e, 0x85}}, + {3, [3]byte{0xef, 0x9e, 0x86}}, {3, [3]byte{0xef, 0x9e, 0x87}}, + {3, [3]byte{0xef, 0x9e, 0x88}}, {3, [3]byte{0xef, 0x9e, 0x89}}, + {3, [3]byte{0xef, 0x9e, 0x8a}}, {3, [3]byte{0xef, 0x9e, 0x8b}}, + {3, [3]byte{0xef, 0x9e, 0x8c}}, {3, [3]byte{0xef, 0x9e, 0x8d}}, + {3, [3]byte{0xef, 0x9e, 0x8e}}, {3, [3]byte{0xef, 0x9e, 0x8f}}, + {3, [3]byte{0xef, 0x9e, 0x90}}, {3, [3]byte{0xef, 0x9e, 0x91}}, + {3, [3]byte{0xef, 0x9e, 0x92}}, {3, [3]byte{0xef, 0x9e, 0x93}}, + {3, [3]byte{0xef, 0x9e, 0x94}}, {3, [3]byte{0xef, 0x9e, 0x95}}, + {3, [3]byte{0xef, 0x9e, 0x96}}, {3, [3]byte{0xef, 0x9e, 0x97}}, + {3, [3]byte{0xef, 0x9e, 0x98}}, {3, [3]byte{0xef, 0x9e, 0x99}}, + {3, [3]byte{0xef, 0x9e, 0x9a}}, {3, [3]byte{0xef, 0x9e, 0x9b}}, + {3, [3]byte{0xef, 0x9e, 0x9c}}, {3, [3]byte{0xef, 0x9e, 0x9d}}, + {3, [3]byte{0xef, 0x9e, 0x9e}}, {3, [3]byte{0xef, 0x9e, 0x9f}}, + {3, [3]byte{0xef, 0x9e, 0xa0}}, {3, [3]byte{0xef, 0x9e, 0xa1}}, + {3, [3]byte{0xef, 0x9e, 0xa2}}, {3, [3]byte{0xef, 0x9e, 0xa3}}, + {3, [3]byte{0xef, 0x9e, 0xa4}}, {3, [3]byte{0xef, 0x9e, 0xa5}}, + {3, [3]byte{0xef, 0x9e, 0xa6}}, {3, [3]byte{0xef, 0x9e, 0xa7}}, + {3, [3]byte{0xef, 0x9e, 0xa8}}, {3, [3]byte{0xef, 0x9e, 0xa9}}, + {3, [3]byte{0xef, 0x9e, 0xaa}}, {3, [3]byte{0xef, 0x9e, 0xab}}, + {3, [3]byte{0xef, 0x9e, 0xac}}, {3, [3]byte{0xef, 0x9e, 0xad}}, + {3, [3]byte{0xef, 0x9e, 0xae}}, {3, [3]byte{0xef, 0x9e, 0xaf}}, + {3, [3]byte{0xef, 0x9e, 0xb0}}, {3, [3]byte{0xef, 0x9e, 0xb1}}, + {3, [3]byte{0xef, 0x9e, 0xb2}}, {3, [3]byte{0xef, 0x9e, 0xb3}}, + {3, [3]byte{0xef, 0x9e, 0xb4}}, {3, [3]byte{0xef, 0x9e, 0xb5}}, + {3, [3]byte{0xef, 0x9e, 0xb6}}, {3, [3]byte{0xef, 0x9e, 0xb7}}, + {3, [3]byte{0xef, 0x9e, 0xb8}}, {3, [3]byte{0xef, 0x9e, 0xb9}}, + {3, [3]byte{0xef, 0x9e, 0xba}}, {3, [3]byte{0xef, 0x9e, 0xbb}}, + {3, [3]byte{0xef, 0x9e, 0xbc}}, {3, [3]byte{0xef, 0x9e, 0xbd}}, + {3, [3]byte{0xef, 0x9e, 0xbe}}, {3, [3]byte{0xef, 0x9e, 0xbf}}, + {3, [3]byte{0xef, 0x9f, 0x80}}, {3, [3]byte{0xef, 0x9f, 0x81}}, + {3, [3]byte{0xef, 0x9f, 0x82}}, {3, [3]byte{0xef, 0x9f, 0x83}}, + {3, [3]byte{0xef, 0x9f, 0x84}}, {3, [3]byte{0xef, 0x9f, 0x85}}, + {3, [3]byte{0xef, 0x9f, 0x86}}, {3, [3]byte{0xef, 0x9f, 0x87}}, + {3, [3]byte{0xef, 0x9f, 0x88}}, {3, [3]byte{0xef, 0x9f, 0x89}}, + {3, [3]byte{0xef, 0x9f, 0x8a}}, {3, [3]byte{0xef, 0x9f, 0x8b}}, + {3, [3]byte{0xef, 0x9f, 0x8c}}, {3, [3]byte{0xef, 0x9f, 0x8d}}, + {3, [3]byte{0xef, 0x9f, 0x8e}}, {3, [3]byte{0xef, 0x9f, 0x8f}}, + {3, [3]byte{0xef, 0x9f, 0x90}}, {3, [3]byte{0xef, 0x9f, 0x91}}, + {3, [3]byte{0xef, 0x9f, 0x92}}, {3, [3]byte{0xef, 0x9f, 0x93}}, + {3, [3]byte{0xef, 0x9f, 0x94}}, {3, [3]byte{0xef, 0x9f, 0x95}}, + {3, [3]byte{0xef, 0x9f, 0x96}}, {3, [3]byte{0xef, 0x9f, 0x97}}, + {3, [3]byte{0xef, 0x9f, 0x98}}, {3, [3]byte{0xef, 0x9f, 0x99}}, + {3, [3]byte{0xef, 0x9f, 0x9a}}, {3, [3]byte{0xef, 0x9f, 0x9b}}, + {3, [3]byte{0xef, 0x9f, 0x9c}}, {3, [3]byte{0xef, 0x9f, 0x9d}}, + {3, [3]byte{0xef, 0x9f, 0x9e}}, {3, [3]byte{0xef, 0x9f, 0x9f}}, + {3, [3]byte{0xef, 0x9f, 0xa0}}, {3, [3]byte{0xef, 0x9f, 0xa1}}, + {3, [3]byte{0xef, 0x9f, 0xa2}}, {3, [3]byte{0xef, 0x9f, 0xa3}}, + {3, [3]byte{0xef, 0x9f, 0xa4}}, {3, [3]byte{0xef, 0x9f, 0xa5}}, + {3, [3]byte{0xef, 0x9f, 0xa6}}, {3, [3]byte{0xef, 0x9f, 0xa7}}, + {3, [3]byte{0xef, 0x9f, 0xa8}}, {3, [3]byte{0xef, 0x9f, 0xa9}}, + {3, [3]byte{0xef, 0x9f, 0xaa}}, {3, [3]byte{0xef, 0x9f, 0xab}}, + {3, [3]byte{0xef, 0x9f, 0xac}}, {3, [3]byte{0xef, 0x9f, 0xad}}, + {3, [3]byte{0xef, 0x9f, 0xae}}, {3, [3]byte{0xef, 0x9f, 0xaf}}, + {3, [3]byte{0xef, 0x9f, 0xb0}}, {3, [3]byte{0xef, 0x9f, 0xb1}}, + {3, [3]byte{0xef, 0x9f, 0xb2}}, {3, [3]byte{0xef, 0x9f, 0xb3}}, + {3, [3]byte{0xef, 0x9f, 0xb4}}, {3, [3]byte{0xef, 0x9f, 0xb5}}, + {3, [3]byte{0xef, 0x9f, 0xb6}}, {3, [3]byte{0xef, 0x9f, 0xb7}}, + {3, [3]byte{0xef, 0x9f, 0xb8}}, {3, [3]byte{0xef, 0x9f, 0xb9}}, + {3, [3]byte{0xef, 0x9f, 0xba}}, {3, [3]byte{0xef, 0x9f, 0xbb}}, + {3, [3]byte{0xef, 0x9f, 0xbc}}, {3, [3]byte{0xef, 0x9f, 0xbd}}, + {3, [3]byte{0xef, 0x9f, 0xbe}}, {3, [3]byte{0xef, 0x9f, 0xbf}}, + }, + encode: [256]uint32{ + 0x00000000, 0x01000001, 0x02000002, 0x03000003, 0x04000004, 0x05000005, 0x06000006, 0x07000007, + 0x08000008, 0x09000009, 0x0a00000a, 0x0b00000b, 0x0c00000c, 0x0d00000d, 0x0e00000e, 0x0f00000f, + 0x10000010, 0x11000011, 0x12000012, 0x13000013, 0x14000014, 0x15000015, 0x16000016, 0x17000017, + 0x18000018, 0x19000019, 0x1a00001a, 0x1b00001b, 0x1c00001c, 0x1d00001d, 0x1e00001e, 0x1f00001f, + 0x20000020, 0x21000021, 0x22000022, 0x23000023, 0x24000024, 0x25000025, 0x26000026, 0x27000027, + 0x28000028, 0x29000029, 0x2a00002a, 0x2b00002b, 0x2c00002c, 0x2d00002d, 0x2e00002e, 0x2f00002f, + 0x30000030, 0x31000031, 0x32000032, 0x33000033, 0x34000034, 0x35000035, 0x36000036, 0x37000037, + 0x38000038, 0x39000039, 0x3a00003a, 0x3b00003b, 0x3c00003c, 0x3d00003d, 0x3e00003e, 0x3f00003f, + 0x40000040, 0x41000041, 0x42000042, 0x43000043, 0x44000044, 0x45000045, 0x46000046, 0x47000047, + 0x48000048, 0x49000049, 0x4a00004a, 0x4b00004b, 0x4c00004c, 0x4d00004d, 0x4e00004e, 0x4f00004f, + 0x50000050, 0x51000051, 0x52000052, 0x53000053, 0x54000054, 0x55000055, 0x56000056, 0x57000057, + 0x58000058, 0x59000059, 0x5a00005a, 0x5b00005b, 0x5c00005c, 0x5d00005d, 0x5e00005e, 0x5f00005f, + 0x60000060, 0x61000061, 0x62000062, 0x63000063, 0x64000064, 0x65000065, 0x66000066, 0x67000067, + 0x68000068, 0x69000069, 0x6a00006a, 0x6b00006b, 0x6c00006c, 0x6d00006d, 0x6e00006e, 0x6f00006f, + 0x70000070, 0x71000071, 0x72000072, 0x73000073, 0x74000074, 0x75000075, 0x76000076, 0x77000077, + 0x78000078, 0x79000079, 0x7a00007a, 0x7b00007b, 0x7c00007c, 0x7d00007d, 0x7e00007e, 0x7f00007f, + 0x8000f780, 0x8100f781, 0x8200f782, 0x8300f783, 0x8400f784, 0x8500f785, 0x8600f786, 0x8700f787, + 0x8800f788, 0x8900f789, 0x8a00f78a, 0x8b00f78b, 0x8c00f78c, 0x8d00f78d, 0x8e00f78e, 0x8f00f78f, + 0x9000f790, 0x9100f791, 0x9200f792, 0x9300f793, 0x9400f794, 0x9500f795, 0x9600f796, 0x9700f797, + 0x9800f798, 0x9900f799, 0x9a00f79a, 0x9b00f79b, 0x9c00f79c, 0x9d00f79d, 0x9e00f79e, 0x9f00f79f, + 0xa000f7a0, 0xa100f7a1, 0xa200f7a2, 0xa300f7a3, 0xa400f7a4, 0xa500f7a5, 0xa600f7a6, 0xa700f7a7, + 0xa800f7a8, 0xa900f7a9, 0xaa00f7aa, 0xab00f7ab, 0xac00f7ac, 0xad00f7ad, 0xae00f7ae, 0xaf00f7af, + 0xb000f7b0, 0xb100f7b1, 0xb200f7b2, 0xb300f7b3, 0xb400f7b4, 0xb500f7b5, 0xb600f7b6, 0xb700f7b7, + 0xb800f7b8, 0xb900f7b9, 0xba00f7ba, 0xbb00f7bb, 0xbc00f7bc, 0xbd00f7bd, 0xbe00f7be, 0xbf00f7bf, + 0xc000f7c0, 0xc100f7c1, 0xc200f7c2, 0xc300f7c3, 0xc400f7c4, 0xc500f7c5, 0xc600f7c6, 0xc700f7c7, + 0xc800f7c8, 0xc900f7c9, 0xca00f7ca, 0xcb00f7cb, 0xcc00f7cc, 0xcd00f7cd, 0xce00f7ce, 0xcf00f7cf, + 0xd000f7d0, 0xd100f7d1, 0xd200f7d2, 0xd300f7d3, 0xd400f7d4, 0xd500f7d5, 0xd600f7d6, 0xd700f7d7, + 0xd800f7d8, 0xd900f7d9, 0xda00f7da, 0xdb00f7db, 0xdc00f7dc, 0xdd00f7dd, 0xde00f7de, 0xdf00f7df, + 0xe000f7e0, 0xe100f7e1, 0xe200f7e2, 0xe300f7e3, 0xe400f7e4, 0xe500f7e5, 0xe600f7e6, 0xe700f7e7, + 0xe800f7e8, 0xe900f7e9, 0xea00f7ea, 0xeb00f7eb, 0xec00f7ec, 0xed00f7ed, 0xee00f7ee, 0xef00f7ef, + 0xf000f7f0, 0xf100f7f1, 0xf200f7f2, 0xf300f7f3, 0xf400f7f4, 0xf500f7f5, 0xf600f7f6, 0xf700f7f7, + 0xf800f7f8, 0xf900f7f9, 0xfa00f7fa, 0xfb00f7fb, 0xfc00f7fc, 0xfd00f7fd, 0xfe00f7fe, 0xff00f7ff, + }, +} +var listAll = []encoding.Encoding{ + CodePage037, + CodePage437, + CodePage850, + CodePage852, + CodePage855, + CodePage858, + CodePage860, + CodePage862, + CodePage863, + CodePage865, + CodePage866, + CodePage1047, + CodePage1140, + ISO8859_1, + ISO8859_2, + ISO8859_3, + ISO8859_4, + ISO8859_5, + ISO8859_6, + ISO8859_6E, + ISO8859_6I, + ISO8859_7, + ISO8859_8, + ISO8859_8E, + ISO8859_8I, + ISO8859_9, + ISO8859_10, + ISO8859_13, + ISO8859_14, + ISO8859_15, + ISO8859_16, + KOI8R, + KOI8U, + Macintosh, + MacintoshCyrillic, + Windows874, + Windows1250, + Windows1251, + Windows1252, + Windows1253, + Windows1254, + Windows1255, + Windows1256, + Windows1257, + Windows1258, + XUserDefined, +} + +// Total table size 87024 bytes (84KiB); checksum: 811C9DC5 diff --git a/vendor/modules.txt b/vendor/modules.txt index 34f34d40..a25200a9 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -177,6 +177,10 @@ github.com/cenkalti/backoff/v4 # github.com/cespare/xxhash/v2 v2.3.0 ## explicit; go 1.11 github.com/cespare/xxhash/v2 +# github.com/chai2010/tiff v0.0.0-20211005095045-4ec2aa243943 +## explicit +github.com/chai2010/tiff +github.com/chai2010/tiff/internal/fax # github.com/chigopher/pathlib v0.19.1 ## explicit; go 1.21 github.com/chigopher/pathlib @@ -195,6 +199,9 @@ github.com/davecgh/go-spew/spew # github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 ## explicit; go 1.17 github.com/decred/dcrd/dcrec/secp256k1/v4 +# github.com/dimchansky/utfbom v1.1.1 +## explicit +github.com/dimchansky/utfbom # github.com/distribution/reference v0.6.0 ## explicit; go 1.20 github.com/distribution/reference @@ -620,6 +627,12 @@ github.com/prometheus/common/model github.com/prometheus/procfs github.com/prometheus/procfs/internal/fs github.com/prometheus/procfs/internal/util +# github.com/richardlehane/mscfb v1.0.6 +## explicit; go 1.18 +github.com/richardlehane/mscfb +# github.com/richardlehane/msoleps v1.0.3 +## explicit +github.com/richardlehane/msoleps/types # github.com/rivo/uniseg v0.4.7 ## explicit; go 1.18 github.com/rivo/uniseg @@ -629,12 +642,19 @@ github.com/rs/zerolog github.com/rs/zerolog/internal/cbor github.com/rs/zerolog/internal/json github.com/rs/zerolog/log +# github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd +## explicit +github.com/rwcarlsen/goexif/exif +github.com/rwcarlsen/goexif/tiff # github.com/sagikazarmark/locafero v0.7.0 ## explicit; go 1.21 github.com/sagikazarmark/locafero # github.com/sagikazarmark/slog-shim v0.1.0 ## explicit; go 1.20 github.com/sagikazarmark/slog-shim +# github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d +## explicit +github.com/saintfish/chardet # github.com/segmentio/asm v1.2.0 ## explicit; go 1.18 github.com/segmentio/asm/base64 @@ -841,6 +861,7 @@ golang.org/x/exp/slog/internal golang.org/x/exp/slog/internal/buffer # golang.org/x/image v0.25.0 ## explicit; go 1.23.0 +golang.org/x/image/bmp golang.org/x/image/ccitt golang.org/x/image/riff golang.org/x/image/vp8 @@ -886,6 +907,7 @@ golang.org/x/term ## explicit; go 1.23.0 golang.org/x/text/cases golang.org/x/text/encoding +golang.org/x/text/encoding/charmap golang.org/x/text/encoding/internal golang.org/x/text/encoding/internal/identifier golang.org/x/text/encoding/unicode