OLD | NEW |
1 /* vim: set ts=8 sw=8 noexpandtab: */ | 1 /* vim: set ts=8 sw=8 noexpandtab: */ |
2 // qcms | 2 // qcms |
3 // Copyright (C) 2009 Mozilla Foundation | 3 // Copyright (C) 2009 Mozilla Foundation |
4 // Copyright (C) 1998-2007 Marti Maria | 4 // Copyright (C) 1998-2007 Marti Maria |
5 // | 5 // |
6 // Permission is hereby granted, free of charge, to any person obtaining | 6 // Permission is hereby granted, free of charge, to any person obtaining |
7 // a copy of this software and associated documentation files (the "Software"), | 7 // a copy of this software and associated documentation files (the "Software"), |
8 // to deal in the Software without restriction, including without limitation | 8 // to deal in the Software without restriction, including without limitation |
9 // the rights to use, copy, modify, merge, publish, distribute, sublicense, | 9 // the rights to use, copy, modify, merge, publish, distribute, sublicense, |
10 // and/or sell copies of the Software, and to permit persons to whom the Softwar
e | 10 // and/or sell copies of the Software, and to permit persons to whom the Softwar
e |
(...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
693 } | 693 } |
694 | 694 |
695 num_in_channels = read_u8(src, offset + 8); | 695 num_in_channels = read_u8(src, offset + 8); |
696 num_out_channels = read_u8(src, offset + 8); | 696 num_out_channels = read_u8(src, offset + 8); |
697 if (num_in_channels > MAX_CHANNELS || num_out_channels > MAX_CHANNELS) | 697 if (num_in_channels > MAX_CHANNELS || num_out_channels > MAX_CHANNELS) |
698 return NULL; | 698 return NULL; |
699 | 699 |
700 // We require 3in/out channels since we only support RGB->XYZ (or RGB->L
AB) | 700 // We require 3in/out channels since we only support RGB->XYZ (or RGB->L
AB) |
701 // XXX: If we remove this restriction make sure that the number of chann
els | 701 // XXX: If we remove this restriction make sure that the number of chann
els |
702 // is less or equal to the maximum number of mAB curves in qcmsint.
h | 702 // is less or equal to the maximum number of mAB curves in qcmsint.
h |
703 » // also check for clut_size overflow. | 703 » // also check for clut_size overflow. Also make sure it's != 0 |
704 if (num_in_channels != 3 || num_out_channels != 3) | 704 if (num_in_channels != 3 || num_out_channels != 3) |
705 return NULL; | 705 return NULL; |
706 | 706 |
707 // some of this data is optional and is denoted by a zero offset | 707 // some of this data is optional and is denoted by a zero offset |
708 // we also use this to track their existance | 708 // we also use this to track their existance |
709 a_curve_offset = read_u32(src, offset + 28); | 709 a_curve_offset = read_u32(src, offset + 28); |
710 clut_offset = read_u32(src, offset + 24); | 710 clut_offset = read_u32(src, offset + 24); |
711 m_curve_offset = read_u32(src, offset + 20); | 711 m_curve_offset = read_u32(src, offset + 20); |
712 matrix_offset = read_u32(src, offset + 16); | 712 matrix_offset = read_u32(src, offset + 16); |
713 b_curve_offset = read_u32(src, offset + 12); | 713 b_curve_offset = read_u32(src, offset + 12); |
714 | 714 |
715 // Convert offsets relative to the tag to relative to the profile | 715 // Convert offsets relative to the tag to relative to the profile |
716 // preserve zero for optional fields | 716 // preserve zero for optional fields |
717 if (a_curve_offset) | 717 if (a_curve_offset) |
718 a_curve_offset += offset; | 718 a_curve_offset += offset; |
719 if (clut_offset) | 719 if (clut_offset) |
720 clut_offset += offset; | 720 clut_offset += offset; |
721 if (m_curve_offset) | 721 if (m_curve_offset) |
722 m_curve_offset += offset; | 722 m_curve_offset += offset; |
723 if (matrix_offset) | 723 if (matrix_offset) |
724 matrix_offset += offset; | 724 matrix_offset += offset; |
725 if (b_curve_offset) | 725 if (b_curve_offset) |
726 b_curve_offset += offset; | 726 b_curve_offset += offset; |
727 | 727 |
728 if (clut_offset) { | 728 if (clut_offset) { |
729 assert (num_in_channels == 3); | 729 assert (num_in_channels == 3); |
730 // clut_size can not overflow since lg(256^num_in_channels) = 24
bits. | 730 // clut_size can not overflow since lg(256^num_in_channels) = 24
bits. |
731 for (i = 0; i < num_in_channels; i++) { | 731 for (i = 0; i < num_in_channels; i++) { |
732 clut_size *= read_u8(src, clut_offset + i); | 732 clut_size *= read_u8(src, clut_offset + i); |
| 733 if (clut_size == 0) { |
| 734 invalid_source(src, "bad clut_size"); |
| 735 } |
733 } | 736 } |
734 } else { | 737 } else { |
735 clut_size = 0; | 738 clut_size = 0; |
736 } | 739 } |
737 | 740 |
738 // 24bits * 3 won't overflow either | 741 // 24bits * 3 won't overflow either |
739 clut_size = clut_size * num_out_channels; | 742 clut_size = clut_size * num_out_channels; |
740 | 743 |
741 if (clut_size > MAX_CLUT_SIZE) | 744 if (clut_size > MAX_CLUT_SIZE) |
742 return NULL; | 745 return NULL; |
743 | 746 |
744 lut = malloc(sizeof(struct lutmABType) + (clut_size) * sizeof(float)); | 747 lut = malloc(sizeof(struct lutmABType) + (clut_size) * sizeof(float)); |
745 if (!lut) | 748 if (!lut) |
746 return NULL; | 749 return NULL; |
747 // we'll fill in the rest below | 750 // we'll fill in the rest below |
748 memset(lut, 0, sizeof(struct lutmABType)); | 751 memset(lut, 0, sizeof(struct lutmABType)); |
749 lut->clut_table = &lut->clut_table_data[0]; | 752 lut->clut_table = &lut->clut_table_data[0]; |
750 | 753 |
751 for (i = 0; i < num_in_channels; i++) { | 754 for (i = 0; i < num_in_channels; i++) { |
752 lut->num_grid_points[i] = read_u8(src, clut_offset + i); | 755 lut->num_grid_points[i] = read_u8(src, clut_offset + i); |
| 756 if (lut->num_grid_points[i] == 0) { |
| 757 invalid_source(src, "bad grid_points"); |
| 758 } |
753 } | 759 } |
754 | 760 |
755 // Reverse the processing of transformation elements for mBA type. | 761 // Reverse the processing of transformation elements for mBA type. |
756 lut->reversed = (type == LUT_MBA_TYPE); | 762 lut->reversed = (type == LUT_MBA_TYPE); |
757 | 763 |
758 lut->num_in_channels = num_in_channels; | 764 lut->num_in_channels = num_in_channels; |
759 lut->num_out_channels = num_out_channels; | 765 lut->num_out_channels = num_out_channels; |
760 | 766 |
761 if (matrix_offset) { | 767 if (matrix_offset) { |
762 // read the matrix if we have it | 768 // read the matrix if we have it |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
825 | 831 |
826 /* I'm not sure why the spec specifies a fixed number of entries for LUT
8 tables even though | 832 /* I'm not sure why the spec specifies a fixed number of entries for LUT
8 tables even though |
827 * they have room for the num_entries fields */ | 833 * they have room for the num_entries fields */ |
828 if (type == LUT8_TYPE) { | 834 if (type == LUT8_TYPE) { |
829 num_input_table_entries = 256; | 835 num_input_table_entries = 256; |
830 num_output_table_entries = 256; | 836 num_output_table_entries = 256; |
831 entry_size = 1; | 837 entry_size = 1; |
832 } else if (type == LUT16_TYPE) { | 838 } else if (type == LUT16_TYPE) { |
833 num_input_table_entries = read_u16(src, offset + 48); | 839 num_input_table_entries = read_u16(src, offset + 48); |
834 num_output_table_entries = read_u16(src, offset + 50); | 840 num_output_table_entries = read_u16(src, offset + 50); |
| 841 if (num_input_table_entries == 0 || num_output_table_entries ==
0) { |
| 842 invalid_source(src, "Bad channel count"); |
| 843 return NULL; |
| 844 } |
835 entry_size = 2; | 845 entry_size = 2; |
836 } else { | 846 } else { |
837 assert(0); // the caller checks that this doesn't happen | 847 assert(0); // the caller checks that this doesn't happen |
838 invalid_source(src, "Unexpected lut type"); | 848 invalid_source(src, "Unexpected lut type"); |
839 return NULL; | 849 return NULL; |
840 } | 850 } |
841 | 851 |
842 in_chan = read_u8(src, offset + 8); | 852 in_chan = read_u8(src, offset + 8); |
843 out_chan = read_u8(src, offset + 9); | 853 out_chan = read_u8(src, offset + 9); |
844 grid_points = read_u8(src, offset + 10); | 854 grid_points = read_u8(src, offset + 10); |
845 | 855 |
846 clut_size = pow(grid_points, in_chan); | 856 clut_size = pow(grid_points, in_chan); |
847 if (clut_size > MAX_CLUT_SIZE) { | 857 if (clut_size > MAX_CLUT_SIZE) { |
| 858 invalid_source(src, "CLUT too large"); |
848 return NULL; | 859 return NULL; |
849 } | 860 } |
850 | 861 |
851 if (in_chan != 3 || out_chan != 3) { | 862 if (in_chan != 3 || out_chan != 3) { |
| 863 invalid_source(src, "CLUT only supports RGB"); |
852 return NULL; | 864 return NULL; |
853 } | 865 } |
854 | 866 |
855 lut = malloc(sizeof(struct lutType) + (num_input_table_entries * in_chan
+ clut_size*out_chan + num_output_table_entries * out_chan)*sizeof(float)); | 867 lut = malloc(sizeof(struct lutType) + (num_input_table_entries * in_chan
+ clut_size*out_chan + num_output_table_entries * out_chan)*sizeof(float)); |
856 if (!lut) { | 868 if (!lut) { |
| 869 invalid_source(src, "CLUT too large"); |
857 return NULL; | 870 return NULL; |
858 } | 871 } |
859 | 872 |
860 /* compute the offsets of tables */ | 873 /* compute the offsets of tables */ |
861 lut->input_table = &lut->table_data[0]; | 874 lut->input_table = &lut->table_data[0]; |
862 lut->clut_table = &lut->table_data[in_chan*num_input_table_entries]; | 875 lut->clut_table = &lut->table_data[in_chan*num_input_table_entries]; |
863 lut->output_table = &lut->table_data[in_chan*num_input_table_entries + c
lut_size*out_chan]; | 876 lut->output_table = &lut->table_data[in_chan*num_input_table_entries + c
lut_size*out_chan]; |
864 | 877 |
865 lut->num_input_table_entries = num_input_table_entries; | 878 lut->num_input_table_entries = num_input_table_entries; |
866 lut->num_output_table_entries = num_output_table_entries; | 879 lut->num_output_table_entries = num_output_table_entries; |
867 » lut->num_input_channels = read_u8(src, offset + 8); | 880 » lut->num_input_channels = in_chan; |
868 » lut->num_output_channels = read_u8(src, offset + 9); | 881 » lut->num_output_channels = out_chan; |
869 » lut->num_clut_grid_points = read_u8(src, offset + 10); | 882 » lut->num_clut_grid_points = grid_points; |
870 lut->e00 = read_s15Fixed16Number(src, offset+12); | 883 lut->e00 = read_s15Fixed16Number(src, offset+12); |
871 lut->e01 = read_s15Fixed16Number(src, offset+16); | 884 lut->e01 = read_s15Fixed16Number(src, offset+16); |
872 lut->e02 = read_s15Fixed16Number(src, offset+20); | 885 lut->e02 = read_s15Fixed16Number(src, offset+20); |
873 lut->e10 = read_s15Fixed16Number(src, offset+24); | 886 lut->e10 = read_s15Fixed16Number(src, offset+24); |
874 lut->e11 = read_s15Fixed16Number(src, offset+28); | 887 lut->e11 = read_s15Fixed16Number(src, offset+28); |
875 lut->e12 = read_s15Fixed16Number(src, offset+32); | 888 lut->e12 = read_s15Fixed16Number(src, offset+32); |
876 lut->e20 = read_s15Fixed16Number(src, offset+36); | 889 lut->e20 = read_s15Fixed16Number(src, offset+36); |
877 lut->e21 = read_s15Fixed16Number(src, offset+40); | 890 lut->e21 = read_s15Fixed16Number(src, offset+40); |
878 lut->e22 = read_s15Fixed16Number(src, offset+44); | 891 lut->e22 = read_s15Fixed16Number(src, offset+44); |
879 | 892 |
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1380 { | 1393 { |
1381 qcms_profile *profile = NULL; | 1394 qcms_profile *profile = NULL; |
1382 FILE *file = _wfopen(path, L"rb"); | 1395 FILE *file = _wfopen(path, L"rb"); |
1383 if (file) { | 1396 if (file) { |
1384 profile = qcms_profile_from_file(file); | 1397 profile = qcms_profile_from_file(file); |
1385 fclose(file); | 1398 fclose(file); |
1386 } | 1399 } |
1387 return profile; | 1400 return profile; |
1388 } | 1401 } |
1389 #endif | 1402 #endif |
OLD | NEW |