1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
//! # PNGer - PNG Steganography Library
//!
//! PNGer is a Rust library for embedding and extracting payloads within PNG images using steganography techniques.
//! It provides both file-based and memory-based APIs for flexibility, with support for various embedding strategies
//! and payload obfuscation methods.
//!
//! ## Key Features
//!
//! - **Embedding Strategies**: For now, only LSB (Least Significant Bit) strategy is supported with linear and random patterns
//! - **Payload Obfuscation**: XOR encryption for additional security
//! - **Cross-platform**: Compatible across different architectures
//! - **Password Protection**: Derive embedding patterns from passwords
//!
//! ## Quick Start
//!
//! ### Basic embedding and extraction from files
//!
//! ```no_run
//! use pnger::{embed_payload_from_file, extract_payload_from_file};
//!
//! // Embed a payload
//! let payload = b"this is a payload";
//! let png_with_payload = embed_payload_from_file("image.png", payload)?;
//! std::fs::write("output.png", png_with_payload)?;
//!
//! // Extract the payload
//! let extracted_payload = extract_payload_from_file("output.png")?;
//! assert_eq!(extracted_payload, payload);
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
//!
//! ### Basic embedding and extraction from bytes
//!
//! ```no_run
//! use pnger::{embed_payload_from_bytes, extract_payload_from_bytes};
//!
//! // Embed a payload
//! let payload = b"this is a payload";
//! let png_bytes = [137u8, 80u8, 78u8, 71u8, 13u8, 10u8, 26u8, 10u8, /* ... */];
//! let png_with_payload = embed_payload_from_bytes(&png_bytes, payload)?;
//!
//! // Extract the payload
//! let extracted_payload = extract_payload_from_bytes(&png_with_payload)?;
//! assert_eq!(&extracted_payload, payload);
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
//!
//! ### Advanced Usage with Options
//!
//! ```no_run
//! use pnger::{embed_payload_from_file_with_options, EmbeddingOptions, Strategy};
//! use pnger::strategy::lsb::{LSBConfig, BitIndex};
//! use pnger::Obfuscation;
//!
//! // Configure random pattern with password protection and XOR obfuscation
//! let strategy = Strategy::LSB(
//! LSBConfig::random()
//! .with_password("my_secret_password".to_string())
//! .with_bit_index(BitIndex::Bit1)
//! );
//! let options = EmbeddingOptions::new_with_obfuscation(
//! strategy,
//! Obfuscation::Xor { key: b"encryption_key".to_vec() }
//! );
//!
//! let payload = b"highly secure secret message";
//! let result = embed_payload_from_file_with_options("image.png", payload, options)?;
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
//!
//! ### Fluent Builder API
//!
//! The fluent builder API provides an ergonomic way to configure embedding options:
//!
//! ```no_run
//! use pnger::{embed_payload_from_file_with_options, EmbeddingOptions};
//! use pnger::strategy::lsb::BitIndex;
//!
//! // Simple linear embedding with XOR encryption
//! let options = EmbeddingOptions::linear()
//! .with_xor_string("my_encryption_key");
//!
//! // Random embedding with password and custom bit index
//! let options = EmbeddingOptions::random_with_password("secure_password")
//! .with_bit_index(BitIndex::Bit2)
//! .with_xor_key(b"additional_layer".to_vec());
//!
//! // Conditional configuration
//! let password = Some("secret".to_string());
//! let options = EmbeddingOptions::random()
//! .with_password_if_some(password)
//! .with_xor_string("encryption_key");
//!
//! let payload = b"fluent API example";
//! let result = embed_payload_from_file_with_options("image.png", payload, options)?;
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
//!
//! ## Embedding Strategies
//!
//! ### LSB (Least Significant Bit)
//!
//! The primary embedding strategy modifies the least significant bits of image pixels:
//!
//! - **Linear Pattern**: Sequential pixel modification (faster, less secure)
//! - **Random Pattern**: Pseudo-random pixel selection (slower, more secure)
//! - **Password Protection**: Derive random patterns from passwords
//! - **Bit Index Selection**: Choose which bit position to modify (0-7)
//!
//! ## Considerations
//!
//! - **Capacity**: 1 byte requires 8 pixels (1 bit per pixel for LSB)
//! - **Random Patterns**: Slightly slower due to PRNG operations
//!
//! ## Error Handling
//!
//! All functions return `Result<T, PngerError>` with comprehensive error types:
//!
//! - **Capacity Errors**: Payload too large for image
//! - **I/O Errors**: File system or PNG format issues
//! - **Crypto Errors**: Random number generation or password derivation failures
//! - **Format Errors**: Invalid PNG structure or corrupted data
use ;
type PayloadSize = u32;
// Re-exports for public API
pub use crateObfuscation;
pub use crateStrategy;
use crateLSBEmbedder;
pub use PngerError;
use read_file;
use setup_png_encoder;
/// Configuration options for payload embedding and extraction operations.
///
/// This struct combines embedding strategy selection with optional payload obfuscation
/// settings. It provides both traditional constructors and a fluent builder API for
/// configuring steganography operations without needing to manage low-level implementation details.
///
/// # Examples
///
/// ## Traditional Constructor API
///
/// ```rust
/// use pnger::{EmbeddingOptions, Strategy};
/// use pnger::strategy::lsb::LSBConfig;
///
/// // Linear pattern (fast, less secure)
/// let options = EmbeddingOptions::new(Strategy::LSB(LSBConfig::linear()));
///
/// // Random pattern with auto-generated seed
/// let options = EmbeddingOptions::new(Strategy::LSB(LSBConfig::random()));
///
/// // Random pattern with password
/// let strategy = Strategy::LSB(
/// LSBConfig::random().with_password("secret123".to_string())
/// );
/// let options = EmbeddingOptions::new(strategy);
/// ```
///
/// ## With Obfuscation
///
/// ```rust
/// use pnger::{EmbeddingOptions, Strategy, Obfuscation};
/// use pnger::strategy::lsb::LSBConfig;
///
/// let strategy = Strategy::LSB(LSBConfig::random());
/// let obfuscation = Obfuscation::Xor { key: b"encryption_key".to_vec() };
/// let options = EmbeddingOptions::new_with_obfuscation(strategy, obfuscation);
/// ```
///
/// ## Fluent Builder API
///
/// The fluent builder API provides an ergonomic way to configure options:
///
/// ```rust
/// use pnger::{EmbeddingOptions};
/// use pnger::strategy::lsb::BitIndex;
///
/// // Linear with XOR encryption
/// let options = EmbeddingOptions::linear()
/// .with_xor_string("my_key");
///
/// // Random with password and custom settings
/// let options = EmbeddingOptions::random_with_password("secure_password")
/// .with_bit_index(BitIndex::Bit1)
/// .with_xor_key(vec![0x42, 0xAA, 0xFF]);
///
/// // Conditional configuration
/// let password = Some("optional_password".to_string());
/// let options = EmbeddingOptions::random()
/// .with_password_if_some(password)
/// .without_obfuscation(); // Remove any previous obfuscation
/// ```
/// Extracts a payload from a PNG file using the default embedding strategy.
///
/// This function reads a PNG file and extracts any payload that was previously embedded
/// using PNGer's steganography techniques. It uses the default LSB strategy with random
/// pattern detection and automatic seed recovery.
///
/// This is the primary extraction function for most use cases, providing a simple
/// interface that handles file I/O and format detection automatically.
///
/// # Returns
///
/// Returns a `Vec<u8>` with the extracted payload data.
///
/// # Examples
///
/// ```no_run
/// use pnger::extract_payload_from_file;
///
/// let payload = extract_payload_from_file("image_with_payload.png")?;
/// println!("Extracted {} bytes", payload.len());
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
///
/// # Errors
///
/// This function will return an error if:
/// - The PNG file cannot be read or doesn't exist
/// - The file is not a valid PNG image
/// - No embedded payload is found in the image
/// - The embedded data is corrupted or incomplete
/// - File I/O operations fail
/// Extracts a payload from a PNG file using custom embedding options.
///
/// This function provides advanced control over the extraction process by allowing
/// you to specify the embedding strategy and obfuscation settings that were used
/// during embedding. This is essential when non-default settings were used.
///
/// # Returns
///
/// Returns a `Vec<u8>` with the extracted payload data.
///
/// # Examples
///
/// ## Extract with Password Protection
///
/// ```no_run
/// use pnger::{extract_payload_from_file_with_options, EmbeddingOptions, Strategy};
/// use pnger::strategy::lsb::LSBConfig;
///
/// let strategy = Strategy::LSB(
/// LSBConfig::random().with_password("secret123".to_string())
/// );
/// let options = EmbeddingOptions::new(strategy);
///
/// let payload = extract_payload_from_file_with_options("protected_image.png", options)?;
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
///
/// ## Extract with Obfuscation
///
/// ```no_run
/// use pnger::{extract_payload_from_file_with_options, EmbeddingOptions, Strategy, Obfuscation};
/// use pnger::strategy::lsb::LSBConfig;
///
/// let strategy = Strategy::LSB(LSBConfig::linear());
/// let obfuscation = Obfuscation::Xor { key: b"encryption_key".to_vec() };
/// let options = EmbeddingOptions::new_with_obfuscation(strategy, obfuscation);
///
/// let payload = extract_payload_from_file_with_options("encrypted_image.png", options )?;
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
///
/// # Errors
///
/// This function will return an error if:
/// - The PNG file cannot be read or doesn't exist
/// - The file is not a valid PNG image
/// - The extraction strategy doesn't match the embedding strategy
/// - Password or seed information is incorrect
/// - Obfuscation settings don't match those used during embedding
/// - No embedded payload is found
/// - File I/O operations fail
/// Extracts a payload from PNG data in memory using the default embedding strategy.
///
/// This function operates entirely in memory, making it ideal for scenarios where
/// you already have PNG data loaded or want to avoid file I/O operations. It uses
/// the default LSB strategy with automatic pattern detection.
///
/// This is the core extraction function used internally by the file-based API and
/// provides the foundation for all extraction operations.
///
/// # Returns
///
/// Returns a `Vec<u8>` with the extracted payload data.
///
/// # Examples
///
/// ```no_run
/// use pnger::extract_payload_from_bytes;
///
/// let png_data = std::fs::read("image_with_payload.png")?;
/// let payload = extract_payload_from_bytes(&png_data)?;
///
/// println!("Extracted payload: {}", String::from_utf8_lossy(&payload));
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
/// # Errors
///
/// This function will return an error if:
/// - The data is not valid PNG format
/// - No embedded payload is found in the image
/// - The embedded data is corrupted or incomplete
/// - PNG decoding operations fail
///
/// # Performance Notes
///
/// - Faster than file-based operations (no I/O overhead)
/// - Memory usage scales with PNG size
/// - Consider memory constraints with very large images
/// Extracts a payload from PNG data using custom embedding options.
///
/// This is the most flexible extraction function, providing full control over the
/// extraction process while operating entirely in memory. It's the foundation for
/// all other extraction functions and handles advanced scenarios like password
/// protection and payload obfuscation.
///
/// # Returns
///
/// Returns a `Vec<u8>` with the extracted payload data.
///
/// # Examples
///
/// ## Advanced Extraction with All Features
///
/// ```no_run
/// use pnger::{extract_payload_from_bytes_with_options, EmbeddingOptions, Strategy, Obfuscation};
/// use pnger::strategy::lsb::{LSBConfig, BitIndex};
///
/// let png_data = std::fs::read("complex_image.png")?;
///
/// // Configure extraction to match embedding settings
/// let strategy = Strategy::LSB(
/// LSBConfig::random()
/// .with_password("my_secret_password".to_string())
/// .with_bit_index(BitIndex::Bit2)
/// );
/// let obfuscation = Obfuscation::Xor { key: b"encryption_key".to_vec() };
/// let options = EmbeddingOptions::new_with_obfuscation(strategy, obfuscation);
///
/// let payload = extract_payload_from_bytes_with_options(&png_data, options)?;
///
/// // The payload is now decrypted and ready to use
/// println!("Secret message: {}", String::from_utf8_lossy(&payload));
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
///
/// ## Batch Processing
///
/// ```rust
/// use pnger::{extract_payload_from_bytes_with_options, EmbeddingOptions, Strategy};
/// use pnger::strategy::lsb::LSBConfig;
///
/// fn process_images(images: Vec<Vec<u8>>) -> Result<Vec<String>, Box<dyn std::error::Error>> {
/// let mut results = Vec::new();
/// for png_data in images {
/// let strategy = Strategy::LSB(LSBConfig::linear());
/// let options = EmbeddingOptions::new(strategy);
/// let payload = extract_payload_from_bytes_with_options(&png_data, options)?;
/// results.push(String::from_utf8(payload)?);
/// }
/// Ok(results)
/// }
/// ```
///
/// # Errors
///
/// This function will return an error if:
/// - The data is not valid PNG format
/// - The extraction strategy doesn't match the embedding strategy
/// - Password or cryptographic settings are incorrect
/// - Obfuscation key doesn't match the one used during embedding
/// - No embedded payload is found or data is corrupted
/// - PNG decoding operations fail
///
/// # Security Considerations
///
/// - Always use the same password that was used during embedding
/// - Obfuscation keys must match exactly (case-sensitive)
/// - Failed extraction may indicate wrong credentials or corrupted data
/// - Consider implementing retry logic with different parameters if needed
// ===== Embedding methods =====
/// Embeds a payload into a PNG file using the default embedding strategy.
///
/// This function takes a PNG file path and payload data, then embeds the payload
/// into the image using the default LSB (Least Significant Bit) strategy with
/// random pattern embedding and auto-generated seed.
///
/// This is the primary embedding function for most use cases, providing a simple
/// interface that handles file I/O operations automatically while maintaining good security.
///
/// # Returns
///
/// Returns the modified PNG data as bytes on success, or a [`PngerError`] on failure.
/// The returned data can be written directly to a file to create the steganographic image.
///
/// # Examples
///
/// ```no_run
/// use pnger::embed_payload_from_file;
///
/// let payload = b"This is my secret message";
/// let result = embed_payload_from_file("source.png", payload)?;
/// std::fs::write("output_with_payload.png", result)?;
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
///
/// ## Embedding Text Messages
///
/// ```no_run
/// use pnger::embed_payload_from_file;
///
/// let secret_message = "Meet me at midnight";
/// let payload = secret_message.as_bytes();
/// let result = embed_payload_from_file("cover_image.png", payload)?;
///
/// // Save the steganographic image
/// std::fs::write("stego_image.png", result)?;
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
///
/// # Errors
///
/// This function will return an error if:
/// - The PNG file cannot be read or doesn't exist
/// - The file is not a valid PNG image
/// - The payload is too large for the image capacity
/// - The image has insufficient pixels for the payload size
/// - File I/O operations fail
/// - PNG encoding/decoding operations fail
///
/// # Capacity Considerations
///
/// The embedding capacity depends on the image size and strategy:
/// - **LSB Strategy**: Requires 8 pixels per payload byte (1 bit per pixel)
/// - **Header Overhead**: Additional pixels needed for metadata storage
/// - **Seed Storage**: Random patterns may embed seed data, consuming more pixels
///
/// For a 1000x1000 pixel image, you can typically embed around 125KB of payload data.
///
/// # Performance Notes
///
/// - File I/O operations add overhead compared to memory-based functions
/// - Random patterns are slightly slower than linear due to PRNG operations
/// - Consider using [`embed_payload_from_bytes`] for better performance in batch operations
/// Embeds a payload into a PNG file using custom embedding options.
///
/// This function provides advanced control over the embedding process, allowing you
/// to specify the embedding strategy, obfuscation settings, and other parameters.
/// It's ideal for scenarios requiring specific security or performance characteristics.
///
/// # Returns
///
/// Returns the modified PNG data as bytes, ready to be written to a file.
///
/// # Examples
///
/// ## Linear Pattern (Fast, Less Secure)
///
/// ```no_run
/// use pnger::{embed_payload_from_file_with_options, EmbeddingOptions, Strategy};
/// use pnger::strategy::lsb::LSBConfig;
///
/// let payload = b"Fast embedding example";
/// let strategy = Strategy::LSB(LSBConfig::linear());
/// let options = EmbeddingOptions::new(strategy);
///
/// let result = embed_payload_from_file_with_options("image.png", payload, options)?;
/// std::fs::write("fast_output.png", result)?;
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
///
/// ## Password-Protected Random Pattern
///
/// ```no_run
/// use pnger::{embed_payload_from_file_with_options, EmbeddingOptions, Strategy};
/// use pnger::strategy::lsb::{LSBConfig, BitIndex};
///
/// let payload = b"Highly secure secret data";
/// let strategy = Strategy::LSB(
/// LSBConfig::random()
/// .with_password("my_secret_password".to_string())
/// .with_bit_index(BitIndex::Bit2) // Use bit position 2 instead of 0
/// );
/// let options = EmbeddingOptions::new(strategy);
///
/// let result = embed_payload_from_file_with_options("image.png", payload, options)?;
/// std::fs::write("secure_output.png", result)?;
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
///
/// ## With XOR Obfuscation
///
/// ```no_run
/// use pnger::{embed_payload_from_file_with_options, EmbeddingOptions, Strategy, Obfuscation};
/// use pnger::strategy::lsb::LSBConfig;
///
/// let payload = b"Double-encrypted secret";
/// let strategy = Strategy::LSB(LSBConfig::random());
/// let obfuscation = Obfuscation::Xor { key: b"encryption_key".to_vec() };
/// let options = EmbeddingOptions::new_with_obfuscation(strategy, obfuscation);
///
/// let result = embed_payload_from_file_with_options("image.png", payload, options)?;
/// std::fs::write("encrypted_output.png", result)?;
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
///
/// # Errors
///
/// This function will return an error if:
/// - The PNG file cannot be read or doesn't exist
/// - The file is not a valid PNG image
/// - The payload is too large for the image capacity
/// - Invalid embedding parameters (e.g., `bit_index` > 7)
/// - Cryptographic operations fail (password derivation, seed generation)
/// - File I/O or PNG processing operations fail
///
/// # Strategy Considerations
///
/// ## Linear vs Random Patterns
///
/// - **Linear**: Faster embedding, sequential pixel modification, easier to detect
/// - **Random**: Slower embedding, scattered pixel modification, harder to detect
///
/// ## Password Protection
///
/// - Uses Argon2 for secure password-to-seed derivation
/// - No seed data is embedded in the image (smaller overhead)
/// - Must remember the exact password for extraction
///
/// ## Bit Index Selection
///
/// - Index 0 (LSB): Most common, good invisibility vs capacity trade-off
/// - Higher indices: Less capacity, potentially more visible, but less predictable
/// Embeds a payload into PNG data in memory using the default embedding strategy.
///
/// This function operates entirely in memory, making it ideal for scenarios where
/// you already have PNG data loaded or want to avoid file I/O operations. It uses
/// the default LSB strategy with random pattern and auto-generated seed for good
/// security with minimal configuration.
///
/// This is the core embedding function used internally by the file-based API and
/// provides the foundation for all embedding operations.
///
/// # Returns
///
/// Returns the modified PNG data as bytes, ready for use or storage.
///
/// # Examples
///
/// ```no_run
/// use pnger::embed_payload_from_bytes;
///
/// let png_bytes = [137u8, 80u8, 78u8, 71u8, 13u8, 10u8, 26u8, 10u8, /* ... */];
/// let payload = b"message to hide";
///
/// let result = embed_payload_from_bytes(&png_bytes, payload)?;
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
///
/// # Errors
///
/// This function will return an error if:
/// - The data is not valid PNG format
/// - The payload is too large for the image capacity
/// - PNG decoding or encoding operations fail
/// - Memory allocation fails
///
/// # Performance Notes
///
/// - Faster than file-based operations (no I/O overhead)
/// - Memory usage scales with PNG size (typically 3-4x the PNG file size during processing)
/// - Ideal for web applications and batch processing
/// - Consider memory constraints with very large images or many concurrent operations
///
/// # Capacity Guidelines
///
/// For LSB embedding, the theoretical capacity is:
/// ```text
/// Capacity ≈ (Image Width × Image Height × Channels) / 8 bytes
/// ```
///
/// Practical capacity is lower due to header overhead:
/// - Small images (< 100KB): ~60-80% of theoretical capacity
/// - Large images (> 1MB): ~90-95% of theoretical capacity
/// Embeds a payload into PNG data using custom embedding options.
///
/// This is the most flexible embedding function, providing full control over the
/// embedding process while operating entirely in memory. It handles all advanced
/// scenarios including custom strategies, password protection, obfuscation, and
/// fine-tuned embedding parameters.
///
/// # Returns
///
/// Returns the modified PNG data as bytes with the embedded payload.
///
/// # Examples
///
/// ## Maximum Security Configuration
///
/// ```no_run
/// use pnger::{embed_payload_from_bytes_with_options, EmbeddingOptions, Strategy, Obfuscation};
/// use pnger::strategy::lsb::{LSBConfig, BitIndex};
///
/// let png_bytes = [137u8, 80u8, 78u8, 71u8, 13u8, 10u8, 26u8, 10u8, /* ... */];
/// let payload = b"super_secret_payload";
///
/// // Configure maximum security
/// let strategy = Strategy::LSB(
/// LSBConfig::random()
/// .with_password("ultra_secure_password_123".to_string())
/// .with_bit_index(BitIndex::Bit2) // Use less predictable bit position
/// );
/// let obfuscation = Obfuscation::Xor {
/// key: b"additional_encryption_layer".to_vec()
/// };
/// let options = EmbeddingOptions::new_with_obfuscation(strategy, obfuscation);
///
/// let png_with_secret_payload = embed_payload_from_bytes_with_options(&png_bytes, payload, options)?;
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
///
/// ## Performance-Optimized Configuration
///
/// ```no_run
/// use pnger::{embed_payload_from_bytes_with_options, EmbeddingOptions, Strategy};
/// use pnger::strategy::lsb::LSBConfig;
///
/// let png_data = std::fs::read("source.png")?;
/// let payload = b"Fast embedding for batch processing";
///
/// // Configure for speed
/// let strategy = Strategy::LSB(LSBConfig::linear()); // Linear is fastest
/// let options = EmbeddingOptions::new(strategy);
///
/// let result = embed_payload_from_bytes_with_options(&png_data, payload, options)?;
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
///
/// ## Custom Bit Index for Multiple Payloads
///
/// ```no_run
/// use pnger::{embed_payload_from_bytes_with_options, EmbeddingOptions, Strategy};
/// use pnger::strategy::lsb::{LSBConfig, BitIndex};
///
/// let mut png_data = std::fs::read("source.png")?;
///
/// // Embed first payload in bit 0
/// let strategy1 = Strategy::LSB(LSBConfig::linear().with_bit_index(BitIndex::Bit0));
/// let options1 = EmbeddingOptions::new(strategy1);
/// png_data = embed_payload_from_bytes_with_options(&png_data, b"First payload", options1)?;
///
/// // Embed second payload in bit 1 (same image)
/// let strategy2 = Strategy::LSB(LSBConfig::linear().with_bit_index(BitIndex::Bit1));
/// let options2 = EmbeddingOptions::new(strategy2);
/// png_data = embed_payload_from_bytes_with_options(&png_data, b"Second payload", options2)?;
///
/// std::fs::write("multi_payload.png", png_data)?;
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
///
/// # Errors
///
/// This function will return an error if:
/// - The data is not valid PNG format
/// - The payload is too large for the image capacity
/// - Invalid embedding parameters (`bit_index` > 7, empty password, etc.)
/// - Cryptographic operations fail (PRNG, password derivation)
/// - PNG processing operations fail
/// - Memory allocation fails
///
/// # Advanced Configuration Guide
///
/// ## Embedding Strategies
///
/// ### Linear Pattern
/// - **Use case**: High-speed batch processing, non-critical data
/// - **Security**: Low (predictable pattern)
/// - **Performance**: Highest
/// - **Detection resistance**: Low
///
/// ### Random Pattern (Auto Seed)
/// - **Use case**: Good security with convenience
/// - **Security**: High (unpredictable pattern)
/// - **Performance**: Medium
/// - **Detection resistance**: High
/// - **Note**: Seed is embedded in image (slight capacity overhead)
///
/// ### Random Pattern (Password)
/// - **Use case**: Maximum security for sensitive data
/// - **Security**: Highest (password-derived seed)
/// - **Performance**: Medium
/// - **Detection resistance**: Highest
/// - **Note**: No seed embedded (maximum capacity)
///
/// ## Bit Index Selection
///
/// - **Index 0 (LSB)**: Standard choice, best invisibility/capacity ratio
/// - **Index 1-2**: Good alternative indices, slightly more visible
/// - **Index 3-7**: Higher visibility, use only for multiple payload scenarios
///
/// ## Obfuscation Methods
///
/// ### XOR Encryption
/// - **Overhead**: Minimal (no size increase)
/// - **Security**: Moderate (depends on key strength)
/// - **Performance**: Excellent (simple bitwise operations)
/// - **Use case**: Additional security layer, key-based access control
type DecodedPngInfo<'a> = ;
/// Decodes PNG data and extracts format information.
///
/// This internal function handles the initial PNG decoding step, creating a reader
/// and extracting metadata needed for subsequent embedding or extraction operations.
///
/// # Returns
///
/// Returns a tuple containing the PNG reader and format information, or an error
/// if the PNG data is invalid or corrupted.
///
/// # Errors
///
/// This function will return an error if:
/// - The data is not valid PNG format
/// - PNG headers are corrupted or malformed
/// - Unsupported PNG variants or extensions
/// Reads raw pixel data from a PNG reader into memory.
///
/// This function extracts the raw image pixel data that will be used for
/// steganographic operations. The data is returned in the format expected
/// by the embedding and extraction algorithms.
///
/// # Returns
///
/// Returns the raw image data as a byte vector, or an error if reading fails.
///
/// # Errors
///
/// This function will return an error if:
/// - PNG data is corrupted or incomplete
/// - Memory allocation fails
/// - PNG decompression fails
/// Encodes image data back into PNG format.
///
/// This function takes modified image data (after embedding operations) and
/// reconstructs a valid PNG file with the same format characteristics as the
/// original image.
///
/// # Returns
///
/// Returns the complete PNG file as bytes, ready for storage or transmission.
///
/// # Errors
///
/// This function will return an error if:
/// - PNG encoding operations fail
/// - Image data size doesn't match expected dimensions
/// - Memory allocation or buffer operations fail